From 75d04c067d4b775755ab3e5043bee7d46dbb2893 Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Sat, 17 Aug 2024 17:18:19 -0700 Subject: [PATCH 1/8] Use black and isort to standardiz python code --- setup.py | 554 +++++++++++++++------ starlink/Atl.py | 331 ++++++------- starlink/Grf.py | 303 +++++++----- starlink/__init__.py | 1 + starlink/ast/test/plothead.py | 10 +- starlink/ast/test/test.py | 873 ++++++++++++++++++++-------------- starlink/ast/test/test_atl.py | 11 +- starlink/ast/test/testplot.py | 3 +- tools/make_attributes.py | 82 ++-- tools/make_exceptions.py | 40 +- 10 files changed, 1359 insertions(+), 849 deletions(-) diff --git a/setup.py b/setup.py index 40f5b9a..8983e00 100644 --- a/setup.py +++ b/setup.py @@ -1,45 +1,47 @@ - from __future__ import print_function -from distutils import ccompiler -from distutils.core import setup, Extension -import sys +import ctypes import os import re -import numpy +import sys import tarfile -import ctypes -from tools import make_exceptions, make_attributes +from distutils import ccompiler +from distutils.core import Extension, setup from textwrap import dedent +import numpy + +from tools import make_attributes, make_exceptions + + def get_version(): - result = None - with open('starlink/ast/Ast.c') as f: - for line in f: - mt = re.search(r'#define\s+PYAST_VERSION\s+"(\S+)"',line) - if mt: - result = mt.group(1) - break - if result is None: - raise RuntimeError("Cannot read pyast version number from starlink/ast/Ast.c") - return result + result = None + with open("starlink/ast/Ast.c") as f: + for line in f: + mt = re.search(r'#define\s+PYAST_VERSION\s+"(\S+)"', line) + if mt: + result = mt.group(1) + break + if result is None: + raise RuntimeError("Cannot read pyast version number from starlink/ast/Ast.c") + return result def check_libyaml(): """check if the C module can be build by trying to compile a small program against the libyaml development library""" - import tempfile - import shutil - - import distutils.sysconfig import distutils.ccompiler + import distutils.sysconfig + import shutil + import tempfile from distutils.errors import CompileError, LinkError - libraries = ['yaml'] + libraries = ["yaml"] # write a temporary .c file to compile - c_code = dedent(""" + c_code = dedent( + """ #include int main(int argc, char* argv[]) @@ -48,11 +50,12 @@ def check_libyaml(): parser = parser; /* prevent warning */ return 0; } - """) - tmp_dir = tempfile.mkdtemp(prefix = 'tmp_ruamel_yaml_') - bin_file_name = os.path.join(tmp_dir, 'test_yaml') - file_name = bin_file_name + '.c' - with open(file_name, 'w') as fp: + """ + ) + tmp_dir = tempfile.mkdtemp(prefix="tmp_ruamel_yaml_") + bin_file_name = os.path.join(tmp_dir, "test_yaml") + file_name = bin_file_name + ".c" + with open(file_name, "w") as fp: fp.write(c_code) # and try to compile it @@ -67,10 +70,10 @@ def check_libyaml(): libraries=libraries, ) except CompileError: - print('libyaml compile error') + print("libyaml compile error") ret_val = False except LinkError: - print('libyaml link error') + print("libyaml link error") ret_val = False else: ret_val = True @@ -79,159 +82,406 @@ def check_libyaml(): return ret_val - - - include_dirs = [] include_dirs.append(numpy.get_include()) -include_dirs.append(os.path.join('.', 'starlink', 'include')) -include_dirs.append(os.path.join('.', 'ast')) -include_dirs.append(os.path.join('.', 'ast', 'src')) +include_dirs.append(os.path.join(".", "starlink", "include")) +include_dirs.append(os.path.join(".", "ast")) +include_dirs.append(os.path.join(".", "ast", "src")) # Create the support files needed for the build. These find the AST # source code using the environment variable AST_SOURCE, so set AST_SOURCE # to point to the AST source code directory distributed with PyAST. -os.environ["AST_SOURCE"] = os.path.join(os.getcwd(), 'ast') -make_exceptions.make_exceptions(os.path.join('starlink', 'ast')) -make_attributes.make_attributes(os.path.join('starlink', 'ast')) +os.environ["AST_SOURCE"] = os.path.join(os.getcwd(), "ast") +make_exceptions.make_exceptions(os.path.join("starlink", "ast")) +make_attributes.make_attributes(os.path.join("starlink", "ast")) # Extract the AST documentation -if not os.path.exists('sun211.htx'): - tar = tarfile.open('ast/sun211.htx_tar') +if not os.path.exists("sun211.htx"): + tar = tarfile.open("ast/sun211.htx_tar") tar.extractall() tar.close() # List the cminpack source files required by AST: -cminpack_c = ('enorm.c', 'lmder.c', 'qrfac.c', 'dpmpar.c', 'lmder1.c', - 'lmpar.c', 'qrsolv.c') +cminpack_c = ("enorm.c", "lmder.c", "qrfac.c", "dpmpar.c", "lmder1.c", "lmpar.c", "qrsolv.c") # List the C source files for implemented AST classes (in ast/src # subdirectory): -ast_c = ('axis.c', 'box.c', 'channel.c', 'circle.c', 'cmpframe.c', - 'cmpmap.c', 'cmpregion.c', 'dsbspecframe.c', 'dssmap.c', - 'ellipse.c', 'error.c', 'fitschan.c', 'fluxframe.c', 'frame.c', - 'frameset.c', 'globals.c', 'grf3d.c', 'grf_2.0.c', 'grf_3.2.c', - 'grf_5.6.c', 'grismmap.c', 'interval.c', 'keymap.c', - 'loader.c', 'lutmap.c', 'mapping.c', 'mathmap.c', 'matrixmap.c', - 'memory.c', 'moc.c', 'mocchan.c', 'normmap.c', 'nullregion.c', - 'object.c', 'pcdmap.c', 'permmap.c', 'plot.c', - 'pointlist.c', 'pointset.c', 'polygon.c', 'polymap.c', - 'prism.c', 'ratemap.c', 'region.c', 'shiftmap.c', - 'skyaxis.c', 'skyframe.c', 'specfluxframe.c', 'specframe.c', - 'sphmap.c', 'stcschan.c', 'timeframe.c', 'timemap.c', - 'tranmap.c', 'unit.c', 'unitmap.c', 'wcsmap.c', - 'winmap.c', 'xml.c', 'xphmap.c', 'zoommap.c', 'specmap.c', - 'slamap.c', 'chebymap.c', 'unitnormmap.c', 'yamlchan.c' ) +ast_c = ( + "axis.c", + "box.c", + "channel.c", + "circle.c", + "cmpframe.c", + "cmpmap.c", + "cmpregion.c", + "dsbspecframe.c", + "dssmap.c", + "ellipse.c", + "error.c", + "fitschan.c", + "fluxframe.c", + "frame.c", + "frameset.c", + "globals.c", + "grf3d.c", + "grf_2.0.c", + "grf_3.2.c", + "grf_5.6.c", + "grismmap.c", + "interval.c", + "keymap.c", + "loader.c", + "lutmap.c", + "mapping.c", + "mathmap.c", + "matrixmap.c", + "memory.c", + "moc.c", + "mocchan.c", + "normmap.c", + "nullregion.c", + "object.c", + "pcdmap.c", + "permmap.c", + "plot.c", + "pointlist.c", + "pointset.c", + "polygon.c", + "polymap.c", + "prism.c", + "ratemap.c", + "region.c", + "shiftmap.c", + "skyaxis.c", + "skyframe.c", + "specfluxframe.c", + "specframe.c", + "sphmap.c", + "stcschan.c", + "timeframe.c", + "timemap.c", + "tranmap.c", + "unit.c", + "unitmap.c", + "wcsmap.c", + "winmap.c", + "xml.c", + "xphmap.c", + "zoommap.c", + "specmap.c", + "slamap.c", + "chebymap.c", + "unitnormmap.c", + "yamlchan.c", +) # List the other required C source files (in ast subdirectory): -ast_c2 = ( 'palwrap.c', 'pyast_extra.c' ) +ast_c2 = ("palwrap.c", "pyast_extra.c") # List the other required C source files (in ast/wcslib subdirectory): -ast_c3 = ( 'proj.c', 'tpn.c', 'wcstrig.c' ) +ast_c3 = ("proj.c", "tpn.c", "wcstrig.c") # List the erfa source files required by AST. -erfa_c = ('a2af.c', 'a2tf.c', 'ab.c', 'af2a.c', 'anp.c', 'anpm.c', - 'apcg.c', 'apcg13.c', 'apci.c', 'apci13.c', 'apco.c', - 'apco13.c', 'apcs.c', 'apcs13.c', 'aper.c', 'aper13.c', - 'apio.c', 'apio13.c', 'atci13.c', 'atciq.c', 'atciqn.c', - 'atciqz.c', 'atco13.c', 'atic13.c', 'aticq.c', 'aticqn.c', - 'atio13.c', 'atioq.c', 'atoc13.c', 'atoi13.c', 'atoiq.c', - 'bi00.c', 'bp00.c', 'bp06.c', 'bpn2xy.c', 'c2i00a.c', - 'c2i00b.c', 'c2i06a.c', 'c2ibpn.c', 'c2ixy.c', 'c2ixys.c', - 'c2s.c', 'c2t00a.c', 'c2t00b.c', 'c2t06a.c', 'c2tcio.c', - 'c2teqx.c', 'c2tpe.c', 'c2txy.c', 'cal2jd.c', 'cp.c', 'cpv.c', - 'cr.c', 'd2dtf.c', 'd2tf.c', 'dat.c', 'dtdb.c', 'dtf2d.c', - 'eceq06.c', 'ecm06.c', 'ee00.c', 'ee00a.c', 'ee00b.c', - 'ee06a.c', 'eect00.c', 'eform.c', 'eo06a.c', 'eors.c', 'epb.c', - 'epb2jd.c', 'epj.c', 'epj2jd.c', 'epv00.c', 'eqec06.c', - 'eqeq94.c', 'era00.c', 'fad03.c', 'fae03.c', 'faf03.c', - 'faju03.c', 'fal03.c', 'falp03.c', 'fama03.c', 'fame03.c', - 'fane03.c', 'faom03.c', 'fapa03.c', 'fasa03.c', 'faur03.c', - 'fave03.c', 'fk52h.c', 'fk5hip.c', 'fk5hz.c', 'fw2m.c', - 'fw2xy.c', 'g2icrs.c', 'gc2gd.c', 'gc2gde.c', 'gd2gc.c', - 'gd2gce.c', 'gmst00.c', 'gmst06.c', 'gmst82.c', 'gst00a.c', - 'gst00b.c', 'gst06.c', 'gst06a.c', 'gst94.c', 'h2fk5.c', - 'hfk5z.c', 'icrs2g.c', 'ir.c', 'jd2cal.c', 'jdcalf.c', 'ld.c', - 'ldn.c', 'ldsun.c', 'lteceq.c', 'ltecm.c', 'lteqec.c', 'ltp.c', - 'ltpb.c', 'ltpecl.c', 'ltpequ.c', 'num00a.c', 'num00b.c', - 'num06a.c', 'numat.c', 'nut00a.c', 'nut00b.c', 'nut06a.c', - 'nut80.c', 'nutm80.c', 'obl06.c', 'obl80.c', 'p06e.c', 'p2pv.c', - 'p2s.c', 'pap.c', 'pas.c', 'pb06.c', 'pdp.c', 'pfw06.c', - 'plan94.c', 'pm.c', 'pmat00.c', 'pmat06.c', 'pmat76.c', 'pmp.c', - 'pmpx.c', 'pmsafe.c', 'pn.c', 'pn00.c', 'pn00a.c', 'pn00b.c', - 'pn06.c', 'pn06a.c', 'pnm00a.c', 'pnm00b.c', 'pnm06a.c', - 'pnm80.c', 'pom00.c', 'ppp.c', 'ppsp.c', 'pr00.c', 'prec76.c', - 'pv2p.c', 'pv2s.c', 'pvdpv.c', 'pvm.c', 'pvmpv.c', 'pvppv.c', - 'pvstar.c', 'pvtob.c', 'pvu.c', 'pvup.c', 'pvxpv.c', 'pxp.c', - 'refco.c', 'rm2v.c', 'rv2m.c', 'rx.c', 'rxp.c', 'rxpv.c', - 'rxr.c', 'ry.c', 'rz.c', 's00.c', 's00a.c', 's00b.c', 's06.c', - 's06a.c', 's2c.c', 's2p.c', 's2pv.c', 's2xpv.c', 'sepp.c', - 'seps.c', 'sp00.c', 'starpm.c', 'starpv.c', 'sxp.c', 'sxpv.c', - 't_erfa_c.c', 'taitt.c', 'taiut1.c', 'taiutc.c', 'tcbtdb.c', - 'tcgtt.c', 'tdbtcb.c', 'tdbtt.c', 'tf2a.c', 'tf2d.c', 'tr.c', - 'trxp.c', 'trxpv.c', 'tttai.c', 'tttcg.c', 'tttdb.c', 'ttut1.c', - 'ut1tai.c', 'ut1tt.c', 'ut1utc.c', 'utctai.c', 'utcut1.c', - 'xy06.c', 'xys00a.c', 'xys00b.c', 'xys06a.c', 'zp.c', 'zpv.c', - 'zr.c') +erfa_c = ( + "a2af.c", + "a2tf.c", + "ab.c", + "af2a.c", + "anp.c", + "anpm.c", + "apcg.c", + "apcg13.c", + "apci.c", + "apci13.c", + "apco.c", + "apco13.c", + "apcs.c", + "apcs13.c", + "aper.c", + "aper13.c", + "apio.c", + "apio13.c", + "atci13.c", + "atciq.c", + "atciqn.c", + "atciqz.c", + "atco13.c", + "atic13.c", + "aticq.c", + "aticqn.c", + "atio13.c", + "atioq.c", + "atoc13.c", + "atoi13.c", + "atoiq.c", + "bi00.c", + "bp00.c", + "bp06.c", + "bpn2xy.c", + "c2i00a.c", + "c2i00b.c", + "c2i06a.c", + "c2ibpn.c", + "c2ixy.c", + "c2ixys.c", + "c2s.c", + "c2t00a.c", + "c2t00b.c", + "c2t06a.c", + "c2tcio.c", + "c2teqx.c", + "c2tpe.c", + "c2txy.c", + "cal2jd.c", + "cp.c", + "cpv.c", + "cr.c", + "d2dtf.c", + "d2tf.c", + "dat.c", + "dtdb.c", + "dtf2d.c", + "eceq06.c", + "ecm06.c", + "ee00.c", + "ee00a.c", + "ee00b.c", + "ee06a.c", + "eect00.c", + "eform.c", + "eo06a.c", + "eors.c", + "epb.c", + "epb2jd.c", + "epj.c", + "epj2jd.c", + "epv00.c", + "eqec06.c", + "eqeq94.c", + "era00.c", + "fad03.c", + "fae03.c", + "faf03.c", + "faju03.c", + "fal03.c", + "falp03.c", + "fama03.c", + "fame03.c", + "fane03.c", + "faom03.c", + "fapa03.c", + "fasa03.c", + "faur03.c", + "fave03.c", + "fk52h.c", + "fk5hip.c", + "fk5hz.c", + "fw2m.c", + "fw2xy.c", + "g2icrs.c", + "gc2gd.c", + "gc2gde.c", + "gd2gc.c", + "gd2gce.c", + "gmst00.c", + "gmst06.c", + "gmst82.c", + "gst00a.c", + "gst00b.c", + "gst06.c", + "gst06a.c", + "gst94.c", + "h2fk5.c", + "hfk5z.c", + "icrs2g.c", + "ir.c", + "jd2cal.c", + "jdcalf.c", + "ld.c", + "ldn.c", + "ldsun.c", + "lteceq.c", + "ltecm.c", + "lteqec.c", + "ltp.c", + "ltpb.c", + "ltpecl.c", + "ltpequ.c", + "num00a.c", + "num00b.c", + "num06a.c", + "numat.c", + "nut00a.c", + "nut00b.c", + "nut06a.c", + "nut80.c", + "nutm80.c", + "obl06.c", + "obl80.c", + "p06e.c", + "p2pv.c", + "p2s.c", + "pap.c", + "pas.c", + "pb06.c", + "pdp.c", + "pfw06.c", + "plan94.c", + "pm.c", + "pmat00.c", + "pmat06.c", + "pmat76.c", + "pmp.c", + "pmpx.c", + "pmsafe.c", + "pn.c", + "pn00.c", + "pn00a.c", + "pn00b.c", + "pn06.c", + "pn06a.c", + "pnm00a.c", + "pnm00b.c", + "pnm06a.c", + "pnm80.c", + "pom00.c", + "ppp.c", + "ppsp.c", + "pr00.c", + "prec76.c", + "pv2p.c", + "pv2s.c", + "pvdpv.c", + "pvm.c", + "pvmpv.c", + "pvppv.c", + "pvstar.c", + "pvtob.c", + "pvu.c", + "pvup.c", + "pvxpv.c", + "pxp.c", + "refco.c", + "rm2v.c", + "rv2m.c", + "rx.c", + "rxp.c", + "rxpv.c", + "rxr.c", + "ry.c", + "rz.c", + "s00.c", + "s00a.c", + "s00b.c", + "s06.c", + "s06a.c", + "s2c.c", + "s2p.c", + "s2pv.c", + "s2xpv.c", + "sepp.c", + "seps.c", + "sp00.c", + "starpm.c", + "starpv.c", + "sxp.c", + "sxpv.c", + "t_erfa_c.c", + "taitt.c", + "taiut1.c", + "taiutc.c", + "tcbtdb.c", + "tcgtt.c", + "tdbtcb.c", + "tdbtt.c", + "tf2a.c", + "tf2d.c", + "tr.c", + "trxp.c", + "trxpv.c", + "tttai.c", + "tttcg.c", + "tttdb.c", + "ttut1.c", + "ut1tai.c", + "ut1tt.c", + "ut1utc.c", + "utctai.c", + "utcut1.c", + "xy06.c", + "xys00a.c", + "xys00b.c", + "xys06a.c", + "zp.c", + "zpv.c", + "zr.c", +) # List the C source files for unimplemeneted AST classes in ast/src: -ast_c_extra = ('fitstable.c', 'intramap.c', 'plot3d.c', 'selectormap.c', - 'stc.c', 'stccatalogentrylocation.c', 'stcobsdatalocation.c', - 'stcresourceprofile.c', 'stcsearchlocation.c', 'switchmap.c', - 'table.c', 'xmlchan.c') +ast_c_extra = ( + "fitstable.c", + "intramap.c", + "plot3d.c", + "selectormap.c", + "stc.c", + "stccatalogentrylocation.c", + "stcobsdatalocation.c", + "stcresourceprofile.c", + "stcsearchlocation.c", + "switchmap.c", + "table.c", + "xmlchan.c", +) # Initialise the list of sources files needed to build the starlink.Ast # module. -sources = [os.path.join('starlink', 'ast', 'Ast.c')] +sources = [os.path.join("starlink", "ast", "Ast.c")] # Append all the .c and .h files needed to build the AST library locally. for cfile in ast_c: - sources.append(os.path.join('ast', 'src', cfile)) + sources.append(os.path.join("ast", "src", cfile)) for cfile in ast_c2: - sources.append(os.path.join('ast', cfile)) + sources.append(os.path.join("ast", cfile)) for cfile in ast_c3: - sources.append(os.path.join('ast', 'wcslib', cfile)) + sources.append(os.path.join("ast", "wcslib", cfile)) for cfile in cminpack_c: - sources.append(os.path.join(os.path.join('ast', 'cminpack'), cfile)) + sources.append(os.path.join(os.path.join("ast", "cminpack"), cfile)) for cfile in erfa_c: - sources.append(os.path.join(os.path.join('ast', 'erfa'), cfile)) + sources.append(os.path.join(os.path.join("ast", "erfa"), cfile)) for cfile in ast_c_extra: - sources.append(os.path.join('ast', 'src', cfile)) + sources.append(os.path.join("ast", "src", cfile)) extra_link_args = [] # Test the compiler define_macros = [] compiler = ccompiler.new_compiler() -if compiler.has_function('strtok_r'): - define_macros.append(('HAVE_STRTOK_R', '1')) +if compiler.has_function("strtok_r"): + define_macros.append(("HAVE_STRTOK_R", "1")) -if compiler.has_function('strerror_r'): - define_macros.append(('HAVE_STRERROR_R', '1')) +if compiler.has_function("strerror_r"): + define_macros.append(("HAVE_STRERROR_R", "1")) -if compiler.has_function('isfinite'): - define_macros.append(('HAVE_DECL_ISFINITE', '1')) +if compiler.has_function("isfinite"): + define_macros.append(("HAVE_DECL_ISFINITE", "1")) if check_libyaml(): - define_macros.append(('YAML', '1')) - extra_link_args.append( "-lyaml" ) + define_macros.append(("YAML", "1")) + extra_link_args.append("-lyaml") # We need to tell AST what type a 64-bit int will have # Not really sure how to determine whether we have int64_t -define_macros.append(('SIZEOF_LONG', ctypes.sizeof(ctypes.c_long))) -define_macros.append(('SIZEOF_LONG_LONG', ctypes.sizeof(ctypes.c_longlong))) +define_macros.append(("SIZEOF_LONG", ctypes.sizeof(ctypes.c_long))) +define_macros.append(("SIZEOF_LONG_LONG", ctypes.sizeof(ctypes.c_longlong))) # Assume we have isnan() available and assume we have a working sscanf # configure would test for these but we no longer run configure -define_macros.append(('HAVE_DECL_ISNAN', '1')) +define_macros.append(("HAVE_DECL_ISNAN", "1")) # Create the description of the starlink.Ast module. -Ast = Extension('starlink.Ast', - include_dirs=include_dirs, - define_macros=define_macros, - sources=sources) +Ast = Extension("starlink.Ast", include_dirs=include_dirs, define_macros=define_macros, sources=sources) # OSX needs to hide all the normal AST symbols to prevent # name clashes when loaded alongside libast itself (eg from pyndf) @@ -248,28 +498,30 @@ def check_libyaml(): extra_link_args.append(symbol_list) -if len( extra_link_args ) > 0: - Ast.extra_link_args = extra_link_args - -setup(name='starlink-pyast', - version=get_version(), - description='A Python wrapper for the Starlink AST library', - url='http://www.starlink.ac.uk/ast', - author='David Berry', - author_email='d.berry@eaobservatory.org', - packages=['starlink'], - package_data={'starlink': [os.path.join('include', 'star', 'pyast.h')]}, - ext_modules=[Ast], - py_modules=['starlink.Grf', 'starlink.Atl'], - classifiers=[ - 'Intended Audience :: Developers', - 'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)', - 'Programming Language :: Python', - 'Programming Language :: C', - 'Topic :: Scientific/Engineering :: Astronomy' - ], - setup_requires=['numpy'], - install_requires=['numpy'],) +if len(extra_link_args) > 0: + Ast.extra_link_args = extra_link_args + +setup( + name="starlink-pyast", + version=get_version(), + description="A Python wrapper for the Starlink AST library", + url="http://www.starlink.ac.uk/ast", + author="David Berry", + author_email="d.berry@eaobservatory.org", + packages=["starlink"], + package_data={"starlink": [os.path.join("include", "star", "pyast.h")]}, + ext_modules=[Ast], + py_modules=["starlink.Grf", "starlink.Atl"], + classifiers=[ + "Intended Audience :: Developers", + "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", + "Programming Language :: Python", + "Programming Language :: C", + "Topic :: Scientific/Engineering :: Astronomy", + ], + setup_requires=["numpy"], + install_requires=["numpy"], +) if os.path.exists(symbol_list): os.unlink(symbol_list) diff --git a/starlink/Atl.py b/starlink/Atl.py index 7a96644..7c56146 100644 --- a/starlink/Atl.py +++ b/starlink/Atl.py @@ -1,11 +1,14 @@ -import starlink.Ast as Ast from distutils.version import LooseVersion +import starlink.Ast as Ast + try: import astropy.io.fits as pyfits + _using_pyfits = False except ImportError: import pyfits + _using_pyfits = True """ @@ -89,34 +92,33 @@ def __init__(self, hdu, clear=True): >>> print("Failed to convert FrameSet to FITS header") """ -# If the supplied object behaves like a sequence, use element zero (the -# primary HDU). Otherwise use the supplied object. + # If the supplied object behaves like a sequence, use element zero (the + # primary HDU). Otherwise use the supplied object. try: self.hdu = hdu[0] except TypeError: self.hdu = hdu -# Initialise the index within the pyfits header of the next card to read or write. + # Initialise the index within the pyfits header of the next card to read or write. self.index = 0 -# The PyFits header may contatenate CONTINUE cards into a single card -# "image". The source function defined below will split such long images up -# into two or more sub-cards. These are managed using the following values. + # The PyFits header may contatenate CONTINUE cards into a single card + # "image". The source function defined below will split such long images up + # into two or more sub-cards. These are managed using the following values. self.subcards = None self.nextsub = 0 self.nsub = 0 -# Record whether the PyFITS header should be emptied before writing to -# it for the first time + # Record whether the PyFITS header should be emptied before writing to + # it for the first time self.clear = clear -# Save a flag indicating if the version of pyfits is 3.1.0 or later -# (some of the earlier API was deprecated at 3.1.0). + # Save a flag indicating if the version of pyfits is 3.1.0 or later + # (some of the earlier API was deprecated at 3.1.0). if _using_pyfits: - self.pre_pyfits_3_1_0 = (LooseVersion(pyfits.__version__) < - LooseVersion("3.1.0")) + self.pre_pyfits_3_1_0 = LooseVersion(pyfits.__version__) < LooseVersion("3.1.0") -# ----------------------------------------------------------------- + # ----------------------------------------------------------------- def astsource(self): """ This method is called by the FitsChan to obtain a single 80-character @@ -126,10 +128,10 @@ def astsource(self): """ if self.subcards is not None: - result = self.subcards[ self.nextsub ] + result = self.subcards[self.nextsub] self.nextsub += 1 if self.nextsub == self.nsub: - self.subcards = None + self.subcards = None elif self.index < len(self.hdu.header.cards): cards = self.hdu.header.cards[self.index].image @@ -137,12 +139,12 @@ def astsource(self): ln = len(cards) if ln <= 80: - result = cards + result = cards else: - self.subcards = [ cards[i:i+80] for i in range(0,len(cards),80)] - self.nsub = len( self.subcards ) - result = self.subcards[ 0 ] - self.nextsub = 1 + self.subcards = [cards[i : i + 80] for i in range(0, len(cards), 80)] + self.nsub = len(self.subcards) + result = self.subcards[0] + self.nextsub = 1 else: result = None @@ -150,7 +152,7 @@ def astsource(self): return result -# ----------------------------------------------------------------- + # ----------------------------------------------------------------- def astsink(self, card): """ This method is called by the FitsChan to store a single 80-character @@ -167,7 +169,7 @@ def astsink(self, card): card = pyfits.Card.fromstring(card) -# Pre pyfits 3.1.0 + # Pre pyfits 3.1.0 if _using_pyfits and self.pre_pyfits_3_1_0: if card.key == "" or card.keyword == "BLANK": self.hdu.header.add_blank() @@ -178,56 +180,56 @@ def astsink(self, card): else: self.hdu.header.update(card.key, card.value, card.comment) -# Astropy, pyfits 3.1.0 and later. + # Astropy, pyfits 3.1.0 and later. else: -# Doesn't seem to be any way to store a CONTINUE card, so all that is -# left is to truncated them by ignoring the continuations :-( - if card.keyword != "CONTINUE": - if isinstance( card.value, str ) and card.value.endswith('&'): - value = card.value[:-1] - else: - value = card.value - self.hdu.header.append((card.keyword,value,card.comment),end=True) - self.index += 1 + # Doesn't seem to be any way to store a CONTINUE card, so all that is + # left is to truncated them by ignoring the continuations :-( + if card.keyword != "CONTINUE": + if isinstance(card.value, str) and card.value.endswith("&"): + value = card.value[:-1] + else: + value = card.value + self.hdu.header.append((card.keyword, value, card.comment), end=True) + self.index += 1 # ====================================================================== def readfitswcs(hdu, Iwc=False): r"""Reads an AST FrameSet from a FITS header. - The header from the specified FITS HDU is read, and an AST FrameSet - describing the WCS information in the header is returned. None is - returned instead of a FrameSet if WCS information cannot be read - from the header. A string identifying the scheme used to describe - WCS information in the header (the encoding) is also returned. - - (frameset,encoding) = starlink.Atl.readfitswcs( hdu ) - - Parameters: - hdu: An element of the hdulist associated with a FITS file - opened using pyfits.open(). If the entire hdulist is supplied, - rather than an element of the hdulist, then the primary HDU - (element zero) will be used. - frameset: A reference to the FrameSet describing the pixel and - world coordinate systems read from the FITS header, or "None" - if no WCS could be read. - encoding: Indicates how the WCS information was encoded in the - header. For possible values, see the documentation for the - "Encoding" attribute in SUN/211. - - Iwc: Include the Intermediate World Coordinate system in the - returned FrameSet, to allow the addition of e.g. a distorted - Cartesian frame between the image frame and sky. - - Example: - >>> import pyfits - >>> import starlink.Atl as Atl - >>> - >>> hdulist = pyfits.open( 'test.fit' ) - >>> (frameset,encoding) = Atl.readfitswcs( hdulist[ 3 ] ) - >>> if frameset == None: - >>> print( "Cannot read WCS from test.fit" ) + The header from the specified FITS HDU is read, and an AST FrameSet + describing the WCS information in the header is returned. None is + returned instead of a FrameSet if WCS information cannot be read + from the header. A string identifying the scheme used to describe + WCS information in the header (the encoding) is also returned. + + (frameset,encoding) = starlink.Atl.readfitswcs( hdu ) + + Parameters: + hdu: An element of the hdulist associated with a FITS file + opened using pyfits.open(). If the entire hdulist is supplied, + rather than an element of the hdulist, then the primary HDU + (element zero) will be used. + frameset: A reference to the FrameSet describing the pixel and + world coordinate systems read from the FITS header, or "None" + if no WCS could be read. + encoding: Indicates how the WCS information was encoded in the + header. For possible values, see the documentation for the + "Encoding" attribute in SUN/211. + + Iwc: Include the Intermediate World Coordinate system in the + returned FrameSet, to allow the addition of e.g. a distorted + Cartesian frame between the image frame and sky. + + Example: + >>> import pyfits + >>> import starlink.Atl as Atl + >>> + >>> hdulist = pyfits.open( 'test.fit' ) + >>> (frameset,encoding) = Atl.readfitswcs( hdulist[ 3 ] ) + >>> if frameset == None: + >>> print( "Cannot read WCS from test.fit" ) """ @@ -247,36 +249,36 @@ def readfitswcs(hdu, Iwc=False): def writefitswcs(frameset, hdu, encoding="FITS-WCS"): r"""Write an AST FrameSet to a FITS file. - The WCS information described by the supplied FrameSet is converted - into a set of FITS header cards which are stored in the supplied - HDU (all cards in the header are first removed). - - nobj = starlink.Atl.writefitswcs( frameset, hdu, encoding="FITS-WCS" ) - - Parameters: - frameset: A reference to the FrameSet to be written out to the - FITS header. - hdu: An element of the PyFITS hdulist associated with a FITS file. - The header cards generated from the FrameSet are stored in the - header associated with this HDU. All cards are first removed - from the header. If an entire hdulist is supplied, rather than - an element of the hdulist, then the primary HDU (element zero) - will be used. - encoding: Indicates how the WCS information is to be encoded in the - header. For possible values, see the documentation for the - "Encoding" attribute in SUN/211. - nobj: - Returned equal to 1 if the FrameSet was converted successfully - to FITS headers using the requested encoding, and zero - otherwise. - Example: - >>> import starlink.Atl as Atl - >>> - >>> (frameset,encoding) = Atl.readfitswcs( hdu1 ) - >>> if Atl.writefitswcs( frameset, hdu2, encoding="FITS-AIPS" ) == 0: - >>> print( "Cannot convert WCS to FITS-AIPS encoding" ) - - """ + The WCS information described by the supplied FrameSet is converted + into a set of FITS header cards which are stored in the supplied + HDU (all cards in the header are first removed). + + nobj = starlink.Atl.writefitswcs( frameset, hdu, encoding="FITS-WCS" ) + + Parameters: + frameset: A reference to the FrameSet to be written out to the + FITS header. + hdu: An element of the PyFITS hdulist associated with a FITS file. + The header cards generated from the FrameSet are stored in the + header associated with this HDU. All cards are first removed + from the header. If an entire hdulist is supplied, rather than + an element of the hdulist, then the primary HDU (element zero) + will be used. + encoding: Indicates how the WCS information is to be encoded in the + header. For possible values, see the documentation for the + "Encoding" attribute in SUN/211. + nobj: + Returned equal to 1 if the FrameSet was converted successfully + to FITS headers using the requested encoding, and zero + otherwise. + Example: + >>> import starlink.Atl as Atl + >>> + >>> (frameset,encoding) = Atl.readfitswcs( hdu1 ) + >>> if Atl.writefitswcs( frameset, hdu2, encoding="FITS-AIPS" ) == 0: + >>> print( "Cannot convert WCS to FITS-AIPS encoding" ) + + """ fitschan = Ast.FitsChan(None, PyFITSAdapter(hdu)) fitschan.Encoding = encoding @@ -287,42 +289,42 @@ def writefitswcs(frameset, hdu, encoding="FITS-WCS"): def plotframeset(axes, gbox, bbox, frameset, options=""): r"""Plot an annotated coordinate grid in a matplotlib axes area. - plot = starlink.Atl.plotframeset( axes, gbox, bbox, frameset, - options="" ) - - Parameters: - axes: A matplotlib "Axes" object. The annotated axes normally - produced by matplotlib will be removed, and axes will - instead be drawn by the AST Plot class. - gbox: A list of four values giving the bounds of the new - annotated axes within the matplotlib Axes object. The supplied - values should be in the order (xleft,ybottom,xright,ytop) and - should be given in the matplotlib "axes" coordinate system. - bbox: A list of four values giving the bounds of the new - annotated axes within the coordinate system represented by the - base Frame of the supplied FrameSet. The supplied values should - be in the order (xleft,ybottom,xright,ytop). - frameset: An AST FrameSet such as returned by the Atl.readfitswcs - function. Its base Frame should be 2-dimensional. - options: An optional string holding a comma-separated list of Plot - attribute settings. These control the appearance of the - annotated axes. - plot: A reference to the Ast.Plot that was used to draw the axes. - - Example: - >>> import pyfits - >>> import starlink.Atl as Atl - >>> import matplotlib.pyplot - >>> - >>> hdulist = pyfits.open( 'test.fit' ) - >>> (frameset,encoding) = starlink.Atl.readfitswcs( hdulist[0] ) - >>> if frameset != None: - >>> naxis1 = hdulist[0].header['NAXIS1'] - >>> naxis2 = hdulist[0].header['NAXIS2'] - >>> Atl.plotframeset( matplotlib.pyplot.figure().add_subplot(111), - >>> [ 0.1, 0.1, 0.9, 0.9 ], - >>> [ 0.5, 0.5, naxis1+0.5, naxis2+0.5 ], frameset ) - >>> matplotlib.pyplot.show() + plot = starlink.Atl.plotframeset( axes, gbox, bbox, frameset, + options="" ) + + Parameters: + axes: A matplotlib "Axes" object. The annotated axes normally + produced by matplotlib will be removed, and axes will + instead be drawn by the AST Plot class. + gbox: A list of four values giving the bounds of the new + annotated axes within the matplotlib Axes object. The supplied + values should be in the order (xleft,ybottom,xright,ytop) and + should be given in the matplotlib "axes" coordinate system. + bbox: A list of four values giving the bounds of the new + annotated axes within the coordinate system represented by the + base Frame of the supplied FrameSet. The supplied values should + be in the order (xleft,ybottom,xright,ytop). + frameset: An AST FrameSet such as returned by the Atl.readfitswcs + function. Its base Frame should be 2-dimensional. + options: An optional string holding a comma-separated list of Plot + attribute settings. These control the appearance of the + annotated axes. + plot: A reference to the Ast.Plot that was used to draw the axes. + + Example: + >>> import pyfits + >>> import starlink.Atl as Atl + >>> import matplotlib.pyplot + >>> + >>> hdulist = pyfits.open( 'test.fit' ) + >>> (frameset,encoding) = starlink.Atl.readfitswcs( hdulist[0] ) + >>> if frameset != None: + >>> naxis1 = hdulist[0].header['NAXIS1'] + >>> naxis2 = hdulist[0].header['NAXIS2'] + >>> Atl.plotframeset( matplotlib.pyplot.figure().add_subplot(111), + >>> [ 0.1, 0.1, 0.9, 0.9 ], + >>> [ 0.5, 0.5, naxis1+0.5, naxis2+0.5 ], frameset ) + >>> matplotlib.pyplot.show() """ import starlink.Grf as Grf @@ -338,36 +340,36 @@ def plotframeset(axes, gbox, bbox, frameset, options=""): # ====================================================================== def plotfitswcs(axes, gbox, hdu, options=""): r"""Read WCS from a PyFITS HDU and plot an annotated coordinate grid - in a matplotlib axes area. The grid covers the entire image. - - plot = starlink.Atl.plotfitswcs( axes, gbox, hdu, options="" ) - - Parameters: - axes: A matplotlib "Axes" object. The annotated axes normally - produced by matplotlib will be removed, and axes will - instead be drawn by the AST Plot class. - gbox: A list of four values giving the bounds of the new - annotated axes within the matplotlib Axes object. The supplied - values should be in the order (xleft,ybottom,xright,ytop) and - should be given in the matplotlib "axes" coordinate system. - hdu: An element of the hdulist associated with a FITS file - opened using pyfits.open(). If the entire hdulist is supplied, - rather than an element of the hdulist, then the primary HDU - (element zero) will be used. - options: An optional string holding a comma-separated list - of Ast.Plot attribute settings. These control the appearance - of the annotated axes. - plot: A reference to the Ast.Plot that was used to draw the axes. - - Example: - >>> import pyfits - >>> import starlink.Atl as Atl - >>> import matplotlib.pyplot - >>> - >>> hdulist = pyfits.open( 'test.fit' ) - >>> Atl.plotfitswcs( matplotlib.pyplot.figure().add_subplot(111), - >>> [ 0.1, 0.1, 0.9, 0.9 ], hdulist ) - >>> matplotlib.pyplot.show() + in a matplotlib axes area. The grid covers the entire image. + + plot = starlink.Atl.plotfitswcs( axes, gbox, hdu, options="" ) + + Parameters: + axes: A matplotlib "Axes" object. The annotated axes normally + produced by matplotlib will be removed, and axes will + instead be drawn by the AST Plot class. + gbox: A list of four values giving the bounds of the new + annotated axes within the matplotlib Axes object. The supplied + values should be in the order (xleft,ybottom,xright,ytop) and + should be given in the matplotlib "axes" coordinate system. + hdu: An element of the hdulist associated with a FITS file + opened using pyfits.open(). If the entire hdulist is supplied, + rather than an element of the hdulist, then the primary HDU + (element zero) will be used. + options: An optional string holding a comma-separated list + of Ast.Plot attribute settings. These control the appearance + of the annotated axes. + plot: A reference to the Ast.Plot that was used to draw the axes. + + Example: + >>> import pyfits + >>> import starlink.Atl as Atl + >>> import matplotlib.pyplot + >>> + >>> hdulist = pyfits.open( 'test.fit' ) + >>> Atl.plotfitswcs( matplotlib.pyplot.figure().add_subplot(111), + >>> [ 0.1, 0.1, 0.9, 0.9 ], hdulist ) + >>> matplotlib.pyplot.show() """ try: @@ -376,7 +378,6 @@ def plotfitswcs(axes, gbox, hdu, options=""): myhdu = hdu (frameset, encoding) = readfitswcs(myhdu) - naxis1 = myhdu.header['NAXIS1'] - naxis2 = myhdu.header['NAXIS2'] - return plotframeset(axes, gbox, [0.5, 0.5, naxis1 + 0.5, naxis2 + 0.5], - frameset, options) + naxis1 = myhdu.header["NAXIS1"] + naxis2 = myhdu.header["NAXIS2"] + return plotframeset(axes, gbox, [0.5, 0.5, naxis1 + 0.5, naxis2 + 0.5], frameset, options) diff --git a/starlink/Grf.py b/starlink/Grf.py index 5054178..d4d585b 100644 --- a/starlink/Grf.py +++ b/starlink/Grf.py @@ -1,8 +1,10 @@ -import starlink.Ast as Ast +import math + import matplotlib -import matplotlib.pyplot import matplotlib.lines -import math +import matplotlib.pyplot + +import starlink.Ast as Ast """ This module provides classes that provide primitive drawing facilities @@ -20,23 +22,22 @@ class grf_matplotlib(object): - """ When creating a grf_matplotlib, the supplied "axes" object should be an instance of the matplotlib Axes class (or a subclass). """ -# ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ def __init__(self, axes): if isinstance(axes, matplotlib.axes.Axes): self.axes = axes self.renderer = None -# Save the current axis scales. + # Save the current axis scales. self.Scales() -# Create a temporary text string and line from which we can determine -# the default graphics properties. + # Create a temporary text string and line from which we can determine + # the default graphics properties. xl, xr = self.axes.get_xlim() yb, yt = self.axes.get_ylim() xc = 0.5 * (xl + xr) @@ -44,99 +45,130 @@ def __init__(self, axes): text = matplotlib.text.Text(xc, yc, "a") line = matplotlib.lines.Line2D([xc], [yc], marker="+") -# Save the current default marker and text sizes. + # Save the current default marker and text sizes. self.__deftsize = text.get_size() self.__defmsize = line.get_markersize() -# Save the default text colour. + # Save the default text colour. defcol = text.get_color() -# Save the default text font family and style. + # Save the default text font family and style. deffont = {"family": text.get_family(), "style": text.get_style()} -# Save the default line style + # Save the default line style defstyle = line.get_linestyle() -# A list used to convert AST integer marker types into matplotlib -# character marker types. - self.markers = ['s', '.', '+', '*', 'o', 'x', ',', '^', 'v', '<', '>', - 'p', 'h', 'D'] - -# A list used to convert AST integer line style types into corresponding matplotlib -# properties. Ensure the first line style is the default. - self.styles = [{"linestyle": defstyle}, {"linestyle": '-'}, - {"linestyle": '--'}, {"linestyle": ':'}, - {"linestyle": '-.'}] - -# A list used to convert AST integer font types into corresponding matplotlib -# properties. Ensure the first font is the default. - self.fonts = [deffont, {"family": 'serif', "style": 'normal'}, - {"family": 'serif', "style": 'italic'}, - {"family": 'sans-serif', "style": 'normal'}, - {"family": 'sans-serif', "style": 'italic'}, - {"family": 'monospace', "style": 'normal'}, - {"family": 'monospace', "style": 'italic'}] - -# A list used to convert AST integer colours into corresponding matplotlib -# properties. Ensure the first colour is the default. - self.colours = [{"color": defcol}, {"color": '#ff0000'}, {"color": '#00ff00'}, - {"color": '#0000ff'}, {"color": '#00ffff'}, - {"color": '#ff00ff'}, {"color": '#ffff00'}, - {"color": '#000000'}, {"color": '#a9a9a9'}, - {"color": '#808080'}, {"color": '#d3d3d3'}, - {"color": '#ffffff'}] - -# The current graphics attribute values as used by AST - self.__attrs = {Ast.grfLINE: {Ast.grfSTYLE: 1, Ast.grfWIDTH: 1, Ast.grfSIZE: 1, - Ast.grfFONT: 1, Ast.grfCOLOUR: 1}, - Ast.grfMARK: {Ast.grfSTYLE: 1, Ast.grfWIDTH: 1, Ast.grfSIZE: 1, - Ast.grfFONT: 1, Ast.grfCOLOUR: 1}, - Ast.grfTEXT: {Ast.grfSTYLE: 1, Ast.grfWIDTH: 1, Ast.grfSIZE: 1, - Ast.grfFONT: 1, Ast.grfCOLOUR: 1}} - -# The corresponding graphics properties used by matplotlib - self.__props = {Ast.grfLINE: {"solid_capstyle": 'butt'}, - Ast.grfMARK: {}, Ast.grfTEXT: {}} - -# Ensure the defaults are current. - for attr in (Ast.grfCOLOUR, Ast.grfWIDTH, Ast.grfSIZE, - Ast.grfFONT, Ast.grfSTYLE): + # A list used to convert AST integer marker types into matplotlib + # character marker types. + self.markers = ["s", ".", "+", "*", "o", "x", ",", "^", "v", "<", ">", "p", "h", "D"] + + # A list used to convert AST integer line style types into corresponding matplotlib + # properties. Ensure the first line style is the default. + self.styles = [ + {"linestyle": defstyle}, + {"linestyle": "-"}, + {"linestyle": "--"}, + {"linestyle": ":"}, + {"linestyle": "-."}, + ] + + # A list used to convert AST integer font types into corresponding matplotlib + # properties. Ensure the first font is the default. + self.fonts = [ + deffont, + {"family": "serif", "style": "normal"}, + {"family": "serif", "style": "italic"}, + {"family": "sans-serif", "style": "normal"}, + {"family": "sans-serif", "style": "italic"}, + {"family": "monospace", "style": "normal"}, + {"family": "monospace", "style": "italic"}, + ] + + # A list used to convert AST integer colours into corresponding matplotlib + # properties. Ensure the first colour is the default. + self.colours = [ + {"color": defcol}, + {"color": "#ff0000"}, + {"color": "#00ff00"}, + {"color": "#0000ff"}, + {"color": "#00ffff"}, + {"color": "#ff00ff"}, + {"color": "#ffff00"}, + {"color": "#000000"}, + {"color": "#a9a9a9"}, + {"color": "#808080"}, + {"color": "#d3d3d3"}, + {"color": "#ffffff"}, + ] + + # The current graphics attribute values as used by AST + self.__attrs = { + Ast.grfLINE: { + Ast.grfSTYLE: 1, + Ast.grfWIDTH: 1, + Ast.grfSIZE: 1, + Ast.grfFONT: 1, + Ast.grfCOLOUR: 1, + }, + Ast.grfMARK: { + Ast.grfSTYLE: 1, + Ast.grfWIDTH: 1, + Ast.grfSIZE: 1, + Ast.grfFONT: 1, + Ast.grfCOLOUR: 1, + }, + Ast.grfTEXT: { + Ast.grfSTYLE: 1, + Ast.grfWIDTH: 1, + Ast.grfSIZE: 1, + Ast.grfFONT: 1, + Ast.grfCOLOUR: 1, + }, + } + + # The corresponding graphics properties used by matplotlib + self.__props = {Ast.grfLINE: {"solid_capstyle": "butt"}, Ast.grfMARK: {}, Ast.grfTEXT: {}} + + # Ensure the defaults are current. + for attr in (Ast.grfCOLOUR, Ast.grfWIDTH, Ast.grfSIZE, Ast.grfFONT, Ast.grfSTYLE): for prim in (Ast.grfTEXT, Ast.grfLINE, Ast.grfMARK): self.Attr(attr, 1.0, prim) -# Set new delimiters for graphical sky axis values, using appropriate escape -# sequences to get he superscripts looking nice. + # Set new delimiters for graphical sky axis values, using appropriate escape + # sequences to get he superscripts looking nice. Ast.tunec("hrdel", "%-%^85+%s70+h%>45+%+") Ast.tunec("mndel", "%-%^85+%s70+m%>45+%+") Ast.tunec("scdel", "%-%^85+%s70+s%>45+%+") Ast.tunec("dgdel", "%-%^90+%s60+o%>45+%+") Ast.tunec("amdel", "%-%^30+%s85+'%>45+%+") - Ast.tunec("asdel", "%-%^30+%s85+\"%>45+%+") + Ast.tunec("asdel", '%-%^30+%s85+"%>45+%+') Ast.tunec("exdel", "10%-%^85+%s60+%>20+") -# Initialise the correction vector for text. + # Initialise the correction vector for text. self._xcorr = 0.0 self._ycorr = 0.0 -# Save the current character heights, and update the vertical offset -# correction for text. + # Save the current character heights, and update the vertical offset + # correction for text. self.Qch() -# Report an error if the supplied object is not suitable + # Report an error if the supplied object is not suitable else: m = axes.__class__.__module__ c = axes.__class__.__name__ if m != "builtins": c = m + "." + c - raise TypeError("The supplied axes object is a " + c + ", it should " - "an instance of matplotlib.axes.Axes or a subclass") - -# ------------------------------------------------------------------------ -# Some backends, such as TkAgg, have the get_renderer method, which #makes this -# easy. Other backends do not have the get_renderer method, so we have a work -# around to find the renderer. Print the figure to a temporary file #object, -# and then grab the renderer that was used. This trick is stolen from the -# matplotlib backend_bases.py print_figure() method. + raise TypeError( + "The supplied axes object is a " + c + ", it should " + "an instance of matplotlib.axes.Axes or a subclass" + ) + + # ------------------------------------------------------------------------ + # Some backends, such as TkAgg, have the get_renderer method, which #makes this + # easy. Other backends do not have the get_renderer method, so we have a work + # around to find the renderer. Print the figure to a temporary file #object, + # and then grab the renderer that was used. This trick is stolen from the + # matplotlib backend_bases.py print_figure() method. def find_renderer(self, fig): @@ -147,42 +179,44 @@ def find_renderer(self, fig): else: try: import io + fig.canvas.print_pdf(io.BytesIO()) self.renderer = fig._cachedRenderer except Exception: pass if not self.renderer: - raise AttributeError("No renderer available using matplotlib " - "backend {0} - use a different backend". - format(matplotlib.get_backend())) + raise AttributeError( + "No renderer available using matplotlib " + "backend {0} - use a different backend".format(matplotlib.get_backend()) + ) - return(self.renderer) + return self.renderer -# ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ def Attr(self, attr, value, prim): # Save the old AST attribute value. oldval = self.__attrs[prim][attr] -# Nothing more to do if the new value is AST__BAD + # Nothing more to do if the new value is AST__BAD if value != Ast.BAD: # Save the old AST attribute value, and record the new value (if not . oldval = self.__attrs[prim][attr] self.__attrs[prim][attr] = value -# Now need to update the matplotlib properties to make them reflect the -# new AST value. + # Now need to update the matplotlib properties to make them reflect the + # new AST value. -# Style only applied to lines + # Style only applied to lines if attr == Ast.grfSTYLE: value = int(value) - 1 if prim == Ast.grfLINE: if value >= 0 and value < len(self.styles): self.__props[prim].update(self.styles[value]) -# Width applies to lines, marks and texts + # Width applies to lines, marks and texts elif attr == Ast.grfWIDTH: if prim == Ast.grfLINE: @@ -190,26 +224,26 @@ def Attr(self, attr, value, prim): xl, xr = self.axes.get_xlim() yb, yt = self.axes.get_ylim() -# Transform to device coords + # Transform to device coords tr = self.axes.transData xl, yb = tr.transform([xl, yb]) xr, yt = tr.transform([xr, yt]) -# Transform to inches + # Transform to inches tr = self.axes.get_figure().dpi_scale_trans.inverted() xl, yb = tr.transform([xl, yb]) xr, yt = tr.transform([xr, yt]) -# Find the length of the diagonal in inches, and convert to points. - diag = 72.0 * math.sqrt((xr - xl)**2 + (yt - yb)**2) + # Find the length of the diagonal in inches, and convert to points. + diag = 72.0 * math.sqrt((xr - xl) ** 2 + (yt - yb) ** 2) -# Find the number of points corresponding to an AST line width of 1.0, -# ensure it is at least 1 point, and then scale it by the supplied AST -# line width. + # Find the number of points corresponding to an AST line width of 1.0, + # ensure it is at least 1 point, and then scale it by the supplied AST + # line width. lw = max(0.0005 * diag, 1.0) * value self.__props[prim].update({"linewidth": lw}) -# Similar for markers + # Similar for markers elif prim == Ast.grfMARK: xl, xr = self.axes.get_xlim() yb, yt = self.axes.get_ylim() @@ -219,11 +253,11 @@ def Attr(self, attr, value, prim): tr = self.axes.get_figure().dpi_scale_trans.inverted() xl, yb = tr.transform([xl, yb]) xr, yt = tr.transform([xr, yt]) - diag = 72.0 * math.sqrt((xr - xl)**2 + (yt - yb)**2) + diag = 72.0 * math.sqrt((xr - xl) ** 2 + (yt - yb) ** 2) lw = max(0.0005 * diag, 1.0) * value self.__props[prim].update({"markeredgewidth": lw}) -# Cannot control exact line width of texts, use weight instead. + # Cannot control exact line width of texts, use weight instead. elif prim == Ast.grfTEXT: if value < 0.0: wgt = 0.0 @@ -235,21 +269,21 @@ def Attr(self, attr, value, prim): wgt = 900 self.__props[prim].update({"weight": wgt}) -# Size applies to marks and texts + # Size applies to marks and texts elif attr == Ast.grfSIZE: if prim == Ast.grfMARK: self.__props[prim].update({"markersize": self.__defmsize * value}) elif prim == Ast.grfTEXT: self.__props[prim].update({"size": self.__deftsize * value}) -# Font only applies to texts + # Font only applies to texts elif attr == Ast.grfFONT: value = int(value) - 1 if prim == Ast.grfTEXT: if value >= 0 and value < len(self.fonts): self.__props[prim].update(self.fonts[value]) -# Colour applied to them all + # Colour applied to them all elif attr == Ast.grfCOLOUR: value = int(value) - 1 if value >= 0 and value < len(self.colours): @@ -257,11 +291,11 @@ def Attr(self, attr, value, prim): return oldval -# ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ def BBuf(self): return -# ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ def Cap(self, cap, value): if cap == Ast.grfSCALES: return 1 @@ -272,32 +306,31 @@ def Cap(self, cap, value): else: return 0 -# ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ def EBuf(self): return -# ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ def Flush(self): return -# ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ def Line(self, n, x, y): - self.axes.add_line(matplotlib.lines.Line2D(x, y, - **self.__props[Ast.grfLINE])) + self.axes.add_line(matplotlib.lines.Line2D(x, y, **self.__props[Ast.grfLINE])) -# ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ def Mark(self, n, x, y, type): if type < 0 or type >= len(self.markers): - marker = '.' + marker = "." else: marker = self.markers[type] props = self.__props[Ast.grfMARK].copy() - props["linestyle"] = 'None' + props["linestyle"] = "None" props["marker"] = marker self.axes.add_line(matplotlib.lines.Line2D(x, y, **props)) -# ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ def Qch(self): xl, xr = self.axes.get_xlim() yb, yt = self.axes.get_ylim() @@ -315,7 +348,7 @@ def Qch(self): return (self._chv, self._chh) -# ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ def Scales(self): xleft, xright = self.axes.get_xlim() ybot, ytop = self.axes.get_ylim() @@ -324,7 +357,7 @@ def Scales(self): self.__beta = (a[1][1] - a[0][1]) / (ytop - ybot) return (self.__alpha, self.__beta) -# ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ def Text(self, text, x, y, just, upx, upy, boxprops={}): if just[0] == "T": va = "top" @@ -342,9 +375,9 @@ def Text(self, text, x, y, just, upx, upy, boxprops={}): ha = "center" rot = math.atan2(-upx, upy) * Ast.DR2D -# matplotlib always seems to plot each text string a little higher than -# requested, sp correct the reference position by a small amount -# determined empirically to produce visually better text positioning. + # matplotlib always seems to plot each text string a little higher than + # requested, sp correct the reference position by a small amount + # determined empirically to produce visually better text positioning. uplen = math.sqrt(upx**2 + upy**2) if uplen > 0.0: x -= upx * self._xcorr / uplen @@ -362,7 +395,7 @@ def Text(self, text, x, y, just, upx, upy, boxprops={}): self.axes.add_artist(otext) return otext -# ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ def TxExt(self, text, x, y, just, upx, upy): otext = self.Text(text, x, y, just, upx, upy, boxprops={"boxstyle": "square,pad=0.0"}) renderer = self.find_renderer(self.axes.get_figure()) @@ -371,66 +404,74 @@ def TxExt(self, text, x, y, just, upx, upy): wcs_verts = otext.get_transform().inverted().transform(pix_verts) otext.remove() - return (wcs_verts[0][0], wcs_verts[1][0], wcs_verts[2][0], wcs_verts[3][0], - wcs_verts[0][1], wcs_verts[1][1], wcs_verts[2][1], wcs_verts[3][1]) - -# ------------------------------------------------------------------------ + return ( + wcs_verts[0][0], + wcs_verts[1][0], + wcs_verts[2][0], + wcs_verts[3][0], + wcs_verts[0][1], + wcs_verts[1][1], + wcs_verts[2][1], + wcs_verts[3][1], + ) + + # ------------------------------------------------------------------------ def ColToInt(self, colour): result = -1 -# If integer, use as is. + # If integer, use as is. try: result = int(colour) -# If not, convert the supplied string to an RGB triple, and then to a -# html hex string. + # If not, convert the supplied string to an RGB triple, and then to a + # html hex string. except ValueError: try: rgb = matplotlib.colors.colorConverter.to_rgb(colour) hex = matplotlib.colors.rgb2hex(rgb) -# Check if this hex string is already in the list of known colours. + # Check if this hex string is already in the list of known colours. index = -1 for item in self.colours: index += 1 - if item['color'] == hex: + if item["color"] == hex: result = index break -# If not, add it to the end. + # If not, add it to the end. if result == -1: self.colours.append({"color": hex}) result = index + 1 -# Return -1 if the supplied colour is not legal. + # Return -1 if the supplied colour is not legal. except ValueError: pass -# GRF colours are zero-based, but AST colours are 1-based. + # GRF colours are zero-based, but AST colours are 1-based. if result != -1: result += 1 return result -# ------------------------------------------------------------------------ + # ------------------------------------------------------------------------ def IntToCol(self, colour): result = None -# Convert from 1-based AST values to zero based Grf values. + # Convert from 1-based AST values to zero based Grf values. colour = int(colour) - 1 -# Check it is in the range of the list of known colours (otherwise we -# reyturn None). + # Check it is in the range of the list of known colours (otherwise we + # reyturn None). if colour >= 0 and colour < len(self.colours): # Get the corresponding colour name (a html hex string). - result = self.colours[colour]['color'].upper() + result = self.colours[colour]["color"].upper() -# Replace the hex string with any corresponding standard colour name. + # Replace the hex string with any corresponding standard colour name. for name, hex in matplotlib.colors.cnames.items(): if hex == result: result = name break -# Return the colour name. + # Return the colour name. return result diff --git a/starlink/__init__.py b/starlink/__init__.py index 9dd960d..fe28036 100644 --- a/starlink/__init__.py +++ b/starlink/__init__.py @@ -19,4 +19,5 @@ """ from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) diff --git a/starlink/ast/test/plothead.py b/starlink/ast/test/plothead.py index 33b916b..b826453 100644 --- a/starlink/ast/test/plothead.py +++ b/starlink/ast/test/plothead.py @@ -3,9 +3,11 @@ from __future__ import print_function import sys + +import matplotlib.pyplot as plt + import starlink.Ast as Ast import starlink.Grf as Grf -import matplotlib.pyplot as plt # Check the header name was supplied on the command line if len(sys.argv) < 2: @@ -22,7 +24,7 @@ fin2 = open(sys.argv[1] + ".fattr") fits_atts = fin2.read() fin2.close() -except (IOError): +except IOError: fits_atts = "" # Attempt to open an associated file holding attributes that control the @@ -32,7 +34,7 @@ fin2 = open(sys.argv[1] + ".attr") plot_atts = fin2.read() fin2.close() -except (IOError): +except IOError: plot_atts = "" # Attempt to open an associated file holding the pixel bounds of the @@ -41,7 +43,7 @@ fin2 = open(sys.argv[1] + ".box") box = [float(v) for v in fin2.read().strip().split()] fin2.close() -except (IOError): +except IOError: box = None # Read the header lines into a list, and store this list in a new diff --git a/starlink/ast/test/test.py b/starlink/ast/test/test.py index 92c2792..1f41055 100644 --- a/starlink/ast/test/test.py +++ b/starlink/ast/test/test.py @@ -1,18 +1,20 @@ -import unittest -import starlink.Ast import copy -import numpy -import math import filecmp -import sys -import os.path +import math import os +import os.path +import sys +import unittest + +import numpy + +import starlink.Ast # A class that defines Channel source and sink functions that store text # in an internal list. -class TextStream(): +class TextStream: def __init__(self): self.reset() @@ -43,14 +45,15 @@ def get(self): # A dummy object used to test channel error reporting. -class DummyStream(): +class DummyStream: pass + # A class that provides primitive graphics operatons for a Plot. All it # does is record the values supplied to it by the Plot class. -class DummyGrf(): +class DummyGrf: def __init__(self): self.Reset() @@ -147,6 +150,7 @@ def ColToInt(self, col): except ValueError: return None + # Tester @@ -163,7 +167,7 @@ def test_Static(self): self.assertEqual(starlink.Ast.tune("ObjectCaching", starlink.Ast.TUNULL), 1) self.assertEqual(starlink.Ast.tune("ObjectCaching", 0), 1) self.assertGreaterEqual(starlink.Ast.version(), 5007002) - self.assertTrue(os.path.isfile(os.path.join(starlink.Ast.get_include(), 'star', 'pyast.h'))) + self.assertTrue(os.path.isfile(os.path.join(starlink.Ast.get_include(), "star", "pyast.h"))) def test_Object(self): with self.assertRaises(TypeError): @@ -255,6 +259,7 @@ def test_FrameSimple(self): self.assertEqual(frame.Label_2, "Axis 2") # Some methods + def test_FrameAngle(self): frame = starlink.Ast.Frame(2) angle = frame.angle([4, 3], [0, 0], [4, 0]) @@ -310,16 +315,15 @@ def test_FrameNorm(self): self.assertEqual(ncoords[0][2], coords[0][2]) self.assertEqual(ncoords[1][0], coords[1][0]) - def test_FrameNormPoints(self): sky = starlink.Ast.SkyFrame() sky.permaxes([2, 1]) - pin = numpy.array([[ 6.1, 6.1, 0.04, 0.04], [ 0.2, -0.2, -0.2, 0.2]]) + pin = numpy.array([[6.1, 6.1, 0.04, 0.04], [0.2, -0.2, -0.2, 0.2]]) pout = sky.normpoints(pin) - self.assertAlmostEqual(pout[0][0], pin[0][0]-2*math.pi) - self.assertAlmostEqual(pout[0][1], pin[0][1]-2*math.pi) + self.assertAlmostEqual(pout[0][0], pin[0][0] - 2 * math.pi) + self.assertAlmostEqual(pout[0][1], pin[0][1] - 2 * math.pi) self.assertAlmostEqual(pout[0][2], pin[0][2]) self.assertAlmostEqual(pout[0][3], pin[0][3]) @@ -328,7 +332,6 @@ def test_FrameNormPoints(self): self.assertAlmostEqual(pout[1][2], pin[1][2]) self.assertAlmostEqual(pout[1][3], pin[1][3]) - def test_FrameOffset(self): frame = starlink.Ast.Frame(2) point = frame.offset([0, 0], [4, 3], 10) @@ -360,8 +363,8 @@ def test_FrameConvert(self): def test_FrameResolve(self): frame = starlink.Ast.Frame(2) point4, d1, d2 = frame.resolve([0, 0], [3, 3], [0, 4]) - self.assertAlmostEqual(d1, 2*math.sqrt(2)) - self.assertAlmostEqual(d2, 2*math.sqrt(2)) + self.assertAlmostEqual(d1, 2 * math.sqrt(2)) + self.assertAlmostEqual(d2, 2 * math.sqrt(2)) def test_FrameUnformat(self): frame = starlink.Ast.Frame(2) @@ -423,30 +426,31 @@ def test_Mapping(self): xin = numpy.linspace(-1, 1, 10) xout = zoommap.tran(xin) - d = (1.2 * xin - xout)**2 + d = (1.2 * xin - xout) ** 2 self.assertEqual(d.sum(), 0.0) - xa = [0., 1., 2., -1., -2., -3., 1., 2., 4., 5.] + xa = [0.0, 1.0, 2.0, -1.0, -2.0, -3.0, 1.0, 2.0, 4.0, 5.0] zoommap.tran(xa, True, xout) - d = (1.2 * numpy.array(xa) - xout)**2 + d = (1.2 * numpy.array(xa) - xout) ** 2 self.assertEqual(d.sum(), 0.0) zoommap = starlink.Ast.ZoomMap(3, 2.0) - pin = numpy.array([[1., 2., 3], [0., 1., 2], [2., 3., 4]]) + pin = numpy.array([[1.0, 2.0, 3], [0.0, 1.0, 2], [2.0, 3.0, 4]]) pout = zoommap.tran(pin, False) - d = (0.5 * pin - pout)**2 + d = (0.5 * pin - pout) ** 2 self.assertEqual(d.sum(), 0.0) zoommap = starlink.Ast.ZoomMap(2, 2.0) pout = zoommap.trangrid([1, 0], [3, 2], 0.001, 100, True) - answer = numpy.array([[2., 4., 6., 2., 4., 6., 2., 4., 6.], - [0., 0., 0., 2., 2., 2., 4., 4., 4.]]) - d = (answer - pout)**2 + answer = numpy.array( + [[2.0, 4.0, 6.0, 2.0, 4.0, 6.0, 2.0, 4.0, 6.0], [0.0, 0.0, 0.0, 2.0, 2.0, 2.0, 4.0, 4.0, 4.0]] + ) + d = (answer - pout) ** 2 self.assertEqual(d.sum(), 0.0) islin, fit = zoommap.linearapprox([1, 0], [3, 2], 0.001) - answer = numpy.array([0., 0., 2., 0., 0., 2.]) - d = (answer - fit)**2 + answer = numpy.array([0.0, 0.0, 2.0, 0.0, 0.0, 2.0]) + d = (answer - fit) ** 2 self.assertEqual(d.sum(), 0.0) self.assertTrue(islin) @@ -460,26 +464,51 @@ def test_Mapping(self): self.assertTrue(isquad) self.assertEqual(rms, 0.0) - answer = numpy.array([0., 2., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0.]) - d = (answer - fit)**2 + answer = numpy.array([0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0]) + d = (answer - fit) ** 2 self.assertEqual(d.sum(), 0.0) self.assertEqual(zoommap.rate([1, 1], 2, 2), 2.0) self.assertEqual(zoommap.rate([1, 1], 1, 2), 0.0) - data_in = numpy.array([[1., 2., 3., ], - [4., 5., 6.], - [7., 8., 9.]]) + data_in = numpy.array( + [ + [ + 1.0, + 2.0, + 3.0, + ], + [4.0, 5.0, 6.0], + [7.0, 8.0, 9.0], + ] + ) zoommap = starlink.Ast.ZoomMap(2, 1.0) - out, outv = zoommap.rebin(0.5, [1, 0], [3, 2], data_in, None, - starlink.Ast.NEAREST, None, starlink.Ast.USEBAD, - 0.0, 100, starlink.Ast.BAD, [2, 0], [5, 2], [1, 0], - [3, 2]) - - answer = numpy.array([[2., 3., starlink.Ast.BAD, starlink.Ast.BAD], - [5., 6., starlink.Ast.BAD, starlink.Ast.BAD], - [8., 9., starlink.Ast.BAD, starlink.Ast.BAD]]) - d = (answer - out)**2 + out, outv = zoommap.rebin( + 0.5, + [1, 0], + [3, 2], + data_in, + None, + starlink.Ast.NEAREST, + None, + starlink.Ast.USEBAD, + 0.0, + 100, + starlink.Ast.BAD, + [2, 0], + [5, 2], + [1, 0], + [3, 2], + ) + + answer = numpy.array( + [ + [2.0, 3.0, starlink.Ast.BAD, starlink.Ast.BAD], + [5.0, 6.0, starlink.Ast.BAD, starlink.Ast.BAD], + [8.0, 9.0, starlink.Ast.BAD, starlink.Ast.BAD], + ] + ) + d = (answer - out) ** 2 self.assertEqual(d.sum(), 0.0) self.assertIsNone(outv) @@ -487,40 +516,92 @@ def test_Mapping(self): data_out = numpy.empty((3, 2), dtype=numpy.intc) # 3 rows 2 cols weights = numpy.zeros((3, 2), dtype=numpy.double) # 3 rows 2 cols -# The bounds supplied to AST here are in the form [col num, row num] + # The bounds supplied to AST here are in the form [col num, row num] flags = starlink.Ast.USEBAD | starlink.Ast.REBININIT nused = 0 - nused = zoommap.rebinseq(0.5, [1, 0], [3, 2], data_in, None, - starlink.Ast.LINEAR, None, flags, - 0.0, 100, -999, [3, 0], [4, 2], - [1, 1], [3, 2], data_out, None, weights, - nused) + nused = zoommap.rebinseq( + 0.5, + [1, 0], + [3, 2], + data_in, + None, + starlink.Ast.LINEAR, + None, + flags, + 0.0, + 100, + -999, + [3, 0], + [4, 2], + [1, 1], + [3, 2], + data_out, + None, + weights, + nused, + ) flags = starlink.Ast.USEBAD | starlink.Ast.REBINEND - nused = zoommap.rebinseq(0.5, [1, 0], [3, 2], data_in, None, - starlink.Ast.LINEAR, None, flags, - 0.0, 100, -999, [3, 0], [4, 2], - [1, 1], [3, 2], data_out, None, weights, - nused) - - answer = numpy.array([[-999, -999], [6., -999], [9., -999]]) - d = (answer - data_out)**2 + nused = zoommap.rebinseq( + 0.5, + [1, 0], + [3, 2], + data_in, + None, + starlink.Ast.LINEAR, + None, + flags, + 0.0, + 100, + -999, + [3, 0], + [4, 2], + [1, 1], + [3, 2], + data_out, + None, + weights, + nused, + ) + + answer = numpy.array([[-999, -999], [6.0, -999], [9.0, -999]]) + d = (answer - data_out) ** 2 self.assertEqual(d.sum(), 0.0) self.assertEqual(nused, 4) - data_in = numpy.array([[1., 2., 3., ], - [4., 5., 6.], - [7., 8., 9.]]) + data_in = numpy.array( + [ + [ + 1.0, + 2.0, + 3.0, + ], + [4.0, 5.0, 6.0], + [7.0, 8.0, 9.0], + ] + ) zoommap = starlink.Ast.ZoomMap(2, 1.0) - npix, out, outv = zoommap.resample([1, 0], [3, 2], data_in, None, - starlink.Ast.NEAREST, None, starlink.Ast.USEBAD, - 0.0, 100, starlink.Ast.BAD, [2, 0], [4, 2], [2, 0], - [4, 2]) - - answer = numpy.array([[2., 3., starlink.Ast.BAD], - [5., 6., starlink.Ast.BAD], - [8., 9., starlink.Ast.BAD]]) - d = (answer - out)**2 + npix, out, outv = zoommap.resample( + [1, 0], + [3, 2], + data_in, + None, + starlink.Ast.NEAREST, + None, + starlink.Ast.USEBAD, + 0.0, + 100, + starlink.Ast.BAD, + [2, 0], + [4, 2], + [2, 0], + [4, 2], + ) + + answer = numpy.array( + [[2.0, 3.0, starlink.Ast.BAD], [5.0, 6.0, starlink.Ast.BAD], [8.0, 9.0, starlink.Ast.BAD]] + ) + d = (answer - out) ** 2 self.assertEqual(d.sum(), 0.0) self.assertIsNone(outv) self.assertEqual(npix, 3) @@ -643,14 +724,13 @@ def test_CmpMap(self): unitmap2 = starlink.Ast.UnitMap(2) zoommap1 = starlink.Ast.ZoomMap(2, 1.5) zoommap2 = starlink.Ast.ZoomMap(2, 2.0) - shiftmap = starlink.Ast.ShiftMap( [-1.0,-1.0] ) + shiftmap = starlink.Ast.ShiftMap([-1.0, -1.0]) maplist = [unitmap1, zoommap1, shiftmap, unitmap2, zoommap2] - invlist = [0,0,0,0,1] - (result,newmaplist,newinvlist) = shiftmap.mapmerge( 2, True, maplist, - invlist ) - self.assertEqual(result,1) - self.assertEqual(len(newmaplist),4) - self.assertEqual(len(newinvlist),4) + invlist = [0, 0, 0, 0, 1] + (result, newmaplist, newinvlist) = shiftmap.mapmerge(2, True, maplist, invlist) + self.assertEqual(result, 1) + self.assertEqual(len(newmaplist), 4) + self.assertEqual(len(newinvlist), 4) self.assertIsInstance(newmaplist[0], starlink.Ast.UnitMap) self.assertIsInstance(newmaplist[1], starlink.Ast.WinMap) self.assertIsInstance(newmaplist[2], starlink.Ast.UnitMap) @@ -687,7 +767,10 @@ def test_SpecFrame(self): refpos = specframe.getrefpos(sky) self.assertAlmostEqual(refpos[0], 0, 5) self.assertAlmostEqual(refpos[1], 1) - self.assertEqual(specframe.InternalUnit_1, specframe.Unit_1, ) + self.assertEqual( + specframe.InternalUnit_1, + specframe.Unit_1, + ) def test_DSBSpecFrame(self): dsbspecframe = starlink.Ast.DSBSpecFrame("IF=4.0,AlignSideBand=1") @@ -718,15 +801,15 @@ def test_FluxFrame(self): self.assertIsInstance(fframe, starlink.Ast.FluxFrame) def test_SpecFluxFrame(self): - sfframe = starlink.Ast.SpecFluxFrame(starlink.Ast.SpecFrame(), - starlink.Ast.FluxFrame(57, starlink.Ast.SpecFrame())) + sfframe = starlink.Ast.SpecFluxFrame( + starlink.Ast.SpecFrame(), starlink.Ast.FluxFrame(57, starlink.Ast.SpecFrame()) + ) self.assertIsInstance(sfframe, starlink.Ast.Frame) self.assertIsInstance(sfframe, starlink.Ast.CmpFrame) self.assertIsInstance(sfframe, starlink.Ast.SpecFluxFrame) def test_Box(self): - box = starlink.Ast.Box(starlink.Ast.Frame(2), 1, - [0, 0], [3, 4]) + box = starlink.Ast.Box(starlink.Ast.Frame(2), 1, [0, 0], [3, 4]) self.assertIsInstance(box, starlink.Ast.Box) self.assertIsInstance(box, starlink.Ast.Region) self.assertIsInstance(box, starlink.Ast.Frame) @@ -734,8 +817,7 @@ def test_Box(self): lbnd, ubnd = box.getregionbounds() self.assertEqual(lbnd[0], 0) self.assertEqual(ubnd[0], 3) - testbox = starlink.Ast.Box(starlink.Ast.Frame(2), 1, - [1, 1], [4, 5]) + testbox = starlink.Ast.Box(starlink.Ast.Frame(2), 1, [1, 1], [4, 5]) overlap = box.overlap(testbox) self.assertEqual(overlap, 4) self.assertTrue(box.removeregions().isaframe()) @@ -746,8 +828,7 @@ def test_Box(self): self.assertAlmostEqual(radius, 2.5000025) def test_MapRegion(self): - box = starlink.Ast.Box(starlink.Ast.Frame(2), 1, - [0, 0], [3, 4]) + box = starlink.Ast.Box(starlink.Ast.Frame(2), 1, [0, 0], [3, 4]) frame = starlink.Ast.Frame(2) mapping = starlink.Ast.ZoomMap(2, 2.0) region = box.mapregion(mapping, frame) @@ -758,37 +839,34 @@ def test_MapRegion(self): self.assertEqual(ubnd[1], 8) def test_mask(self): - box = starlink.Ast.Box(starlink.Ast.Frame(2), 1, - [-0.5,-0.5], [5.5,4.5]) - data = numpy.full((10,15), 7, dtype=int) + box = starlink.Ast.Box(starlink.Ast.Frame(2), 1, [-0.5, -0.5], [5.5, 4.5]) + data = numpy.full((10, 15), 7, dtype=int) map = starlink.Ast.UnitMap(2) -# lbnd/ubnd are given as (col,row) (F77 order). This may seem odd in python, -# but then the same is done when using AST from C. - nmasked = box.mask( map, True, [-3,2], [11,11], data, 0 ) + # lbnd/ubnd are given as (col,row) (F77 order). This may seem odd in python, + # but then the same is done when using AST from C. + nmasked = box.mask(map, True, [-3, 2], [11, 11], data, 0) self.assertEqual(nmasked, 18) - self.assertEqual(data[0,2], 7) - self.assertEqual(data[0,3], 0) - self.assertEqual(data[2,2], 7) - self.assertEqual(data[2,3], 0) - self.assertEqual(data[3,2], 7) - self.assertEqual(data[3,3], 7) - self.assertEqual(data[0,8], 0) - self.assertEqual(data[0,9], 7) - self.assertEqual(data[2,8], 0) - self.assertEqual(data[2,9], 7) - self.assertEqual(data[3,8], 7) - self.assertEqual(data[3,9], 7) + self.assertEqual(data[0, 2], 7) + self.assertEqual(data[0, 3], 0) + self.assertEqual(data[2, 2], 7) + self.assertEqual(data[2, 3], 0) + self.assertEqual(data[3, 2], 7) + self.assertEqual(data[3, 3], 7) + self.assertEqual(data[0, 8], 0) + self.assertEqual(data[0, 9], 7) + self.assertEqual(data[2, 8], 0) + self.assertEqual(data[2, 9], 7) + self.assertEqual(data[3, 8], 7) + self.assertEqual(data[3, 9], 7) def test_Circle(self): - circle = starlink.Ast.Circle(starlink.Ast.Frame(2), 0, - [0, 0], [3, 4]) + circle = starlink.Ast.Circle(starlink.Ast.Frame(2), 0, [0, 0], [3, 4]) self.assertIsInstance(circle, starlink.Ast.Circle) self.assertIsInstance(circle, starlink.Ast.Region) self.assertIsInstance(circle, starlink.Ast.Frame) self.assertIsInstance(circle.getregionframe(), starlink.Ast.Frame) - testcircle = starlink.Ast.Circle(starlink.Ast.Frame(2), 1, - [0, 0], 5) + testcircle = starlink.Ast.Circle(starlink.Ast.Frame(2), 1, [0, 0], 5) overlap = circle.overlap(testcircle) self.assertEqual(overlap, 5) centre, radius, p1 = circle.circlepars() @@ -798,12 +876,11 @@ def test_Circle(self): self.assertEqual(p1[0], 3) self.assertEqual(p1[1], 4) - self.assertTrue( testcircle.pointinregion( [4.5,0.0] ) ) - self.assertFalse( testcircle.pointinregion( [5.5,0.0] ) ) + self.assertTrue(testcircle.pointinregion([4.5, 0.0])) + self.assertFalse(testcircle.pointinregion([5.5, 0.0])) def test_Ellipse(self): - ell = starlink.Ast.Ellipse(starlink.Ast.Frame(2), 0, - [0, 0], [3, 4], [2, 3]) + ell = starlink.Ast.Ellipse(starlink.Ast.Frame(2), 0, [0, 0], [3, 4], [2, 3]) self.assertIsInstance(ell, starlink.Ast.Ellipse) self.assertIsInstance(ell, starlink.Ast.Region) self.assertIsInstance(ell, starlink.Ast.Frame) @@ -830,17 +907,14 @@ def test_Interval(self): self.assertIsInstance(interval, starlink.Ast.Region) def test_CmpRegion(self): - circle = starlink.Ast.Circle(starlink.Ast.Frame(2), 0, - [0, 0], [3, 4]) - box = starlink.Ast.Box(starlink.Ast.Frame(2), 1, - [0, 0], [3, 4]) + circle = starlink.Ast.Circle(starlink.Ast.Frame(2), 0, [0, 0], [3, 4]) + box = starlink.Ast.Box(starlink.Ast.Frame(2), 1, [0, 0], [3, 4]) cmp = starlink.Ast.CmpRegion(circle, box, starlink.Ast.AND) self.assertIsInstance(cmp, starlink.Ast.CmpRegion) self.assertIsInstance(cmp, starlink.Ast.Region) def test_Prism(self): - circle = starlink.Ast.Circle(starlink.Ast.Frame(2), 0, - [0, 0], [3, 4]) + circle = starlink.Ast.Circle(starlink.Ast.Frame(2), 0, [0, 0], [3, 4]) interval = starlink.Ast.Interval(starlink.Ast.Frame(1), [6], [100]) prism = starlink.Ast.Prism(circle, interval) self.assertIsInstance(prism, starlink.Ast.Prism) @@ -889,26 +963,28 @@ def test_MyChannel(self): self.assertEqual(a, b) def test_FitsChan(self): - mycards = ("NAXIS1 = 200 ", - "NAXIS2 = 200 ", - "CTYPE1 = 'RA--TAN ' ", - "CTYPE2 = 'DEC-TAN ' ", - "CRPIX1 = 100 ", - "CRPIX2 = 100 ", - "CDELT1 = 0.001 ", - "CDELT2 = 0.001 ", - "CRVAL1 = 0 ", - "CRVAL2 = 0 ") + mycards = ( + "NAXIS1 = 200 ", + "NAXIS2 = 200 ", + "CTYPE1 = 'RA--TAN ' ", + "CTYPE2 = 'DEC-TAN ' ", + "CRPIX1 = 100 ", + "CRPIX2 = 100 ", + "CDELT1 = 0.001 ", + "CDELT2 = 0.001 ", + "CRVAL1 = 0 ", + "CRVAL2 = 0 ", + ) fc = starlink.Ast.FitsChan(mycards) self.assertIsInstance(fc, starlink.Ast.Object) self.assertEqual(fc["CRVAL1"], 0.0) - self.assertEqual(len(fc),10) + self.assertEqual(len(fc), 10) keywords = fc.keys() - self.assertEqual(len(keywords),10) - self.assertEqual(keywords[0], 'NAXIS1' ) - self.assertEqual(keywords[4], 'CRPIX1' ) - self.assertEqual(keywords[9], 'CRVAL2' ) + self.assertEqual(len(keywords), 10) + self.assertEqual(keywords[0], "NAXIS1") + self.assertEqual(keywords[4], "CRPIX1") + self.assertEqual(keywords[9], "CRVAL2") fc = starlink.Ast.FitsChan() self.assertIsInstance(fc, starlink.Ast.Object) @@ -945,8 +1021,10 @@ def test_FitsChan(self): fc.emptyfits() self.assertEqual(fc.Ncard, 0) - cards = "CRVAL1 = 0 " \ + cards = ( + "CRVAL1 = 0 " "CRVAL2 = 0 " + ) fc.putcards(cards) self.assertEqual(fc.Card, 1) fc.set("Card=10") @@ -962,22 +1040,25 @@ def test_FitsChan(self): self.assertEqual(fc.Encoding, "FITS-WCS") there, card = fc.findfits("%f", False) self.assertTrue(there) - self.assertEqual(card, - "CRVAL1 = 0 ") + self.assertEqual( + card, "CRVAL1 = 0 " + ) fc.delfits() self.assertEqual(fc.Ncard, 9) self.assertEqual(fc.Card, 9) there, card = fc.findfits("%f", False) self.assertTrue(there) - self.assertEqual(card, - "CRVAL2 = 0 ") + self.assertEqual( + card, "CRVAL2 = 0 " + ) fc.putfits("CRVAL1 = 0", False) self.assertEqual(fc.Ncard, 10) self.assertEqual(fc.Card, 10) there, card = fc.findfits("%f", False) self.assertTrue(there) - self.assertEqual(card, - "CRVAL2 = 0 ") + self.assertEqual( + card, "CRVAL2 = 0 " + ) for cards in zip(fc, mycards): self.assertEqual(cards[0], cards[1]) @@ -1077,8 +1158,9 @@ def test_FitsChan_AsMapping(self): self.assertTrue("NAXIS1" in fc) self.assertEqual(len(fc), 10) - self.assertEqual(fc[2], - "CTYPE1 = 'RA--TAN ' ") + self.assertEqual( + fc[2], "CTYPE1 = 'RA--TAN ' " + ) obj = fc.read() self.assertIsInstance(obj, starlink.Ast.FrameSet) self.assertEqual(len(fc), 2) @@ -1105,15 +1187,17 @@ def test_FitsChan_AsMapping(self): self.assertEqual(len(fc), 2) fc[100] = "CTYPE1 = 'RA--TAN ' " - self.assertEqual(fc[2], - "CTYPE1 = 'RA--TAN ' ") + self.assertEqual( + fc[2], "CTYPE1 = 'RA--TAN ' " + ) self.assertEqual(fc.Ncard, 3) self.assertEqual(fc.Nkey, 3) self.assertEqual(len(fc), 3) fc[0] = "NEWKEY = 123.456" - self.assertEqual(fc[0], - "NEWKEY = 123.456 ") + self.assertEqual( + fc[0], "NEWKEY = 123.456 " + ) self.assertEqual(fc.Ncard, 3) self.assertEqual(fc.Nkey, 3) self.assertEqual(len(fc), 3) @@ -1151,11 +1235,11 @@ def test_YamlChan(self): self.assertTrue(ch.isachannel()) self.assertTrue(ch.isaobject()) - f1 = starlink.Ast.Frame( 2, "Domain=PIXEL" ) + f1 = starlink.Ast.Frame(2, "Domain=PIXEL") frameset = starlink.Ast.FrameSet(f1) zoommap = starlink.Ast.ZoomMap(2, 0.01, "Ident=Hello there") - f2 = starlink.Ast.SkyFrame( "System=ICRS" ) - frameset.addframe( starlink.Ast.BASE, zoommap, f2 ) + f2 = starlink.Ast.SkyFrame("System=ICRS") + frameset.addframe(starlink.Ast.BASE, zoommap, f2) ch.SinkFile = "fred.asdf" n = ch.write(frameset) @@ -1185,19 +1269,19 @@ def test_KeyMap(self): self.assertTrue(km.isakeymap()) self.assertTrue(km.isaobject()) self.assertEqual(len(km), 0) - km['Hello'] = 'fred' + km["Hello"] = "fred" self.assertEqual(len(km), 1) - self.assertEqual(km['hELlo'], 'fred') - km['Hello'] = None + self.assertEqual(km["hELlo"], "fred") + km["Hello"] = None self.assertEqual(len(km), 0) - km['TTT'] = (1.2, 3, 4.5) + km["TTT"] = (1.2, 3, 4.5) self.assertEqual(len(km), 1) - self.assertEqual(km['ttt'], (1.2, 3, 4.5)) - km['SS'] = 'hello' + self.assertEqual(km["ttt"], (1.2, 3, 4.5)) + km["SS"] = "hello" self.assertEqual(len(km), 2) - self.assertEqual(km[0], ('TTT', (1.2, 3.0, 4.5))) - self.assertEqual(km[1], ('SS', 'hello')) + self.assertEqual(km[0], ("TTT", (1.2, 3.0, 4.5))) + self.assertEqual(km[1], ("SS", "hello")) self.assertTrue("SS" in km) i = 0 @@ -1207,19 +1291,17 @@ def test_KeyMap(self): km[0] = None self.assertEqual(len(km), 1) - self.assertEqual(km[0], ('SS', 'hello')) - km[0] = 'Goofbye' - self.assertEqual(km[0], ('SS', 'Goofbye')) + self.assertEqual(km[0], ("SS", "hello")) + km[0] = "Goofbye" + self.assertEqual(km[0], ("SS", "Goofbye")) with self.assertRaises(starlink.Ast.MPIND): - km[1] = 'Nooooooo' + km[1] = "Nooooooo" def test_Plot(self): with self.assertRaises(TypeError): - plot = starlink.Ast.Plot(None, [0.0, 0.0, 1.0, 1.0], [0.0, 0.0, 1.0, 1.0], - TextStream()) + plot = starlink.Ast.Plot(None, [0.0, 0.0, 1.0, 1.0], [0.0, 0.0, 1.0, 1.0], TextStream()) mygrf = DummyGrf() - plot = starlink.Ast.Plot(None, [0.0, 0.0, 1.0, 1.0], [0.0, 0.0, 1.0, 1.0], - mygrf) + plot = starlink.Ast.Plot(None, [0.0, 0.0, 1.0, 1.0], [0.0, 0.0, 1.0, 1.0], mygrf) self.assertIsInstance(plot, starlink.Ast.Object) self.assertIsInstance(plot, starlink.Ast.Mapping) self.assertIsInstance(plot, starlink.Ast.Frame) @@ -1250,29 +1332,130 @@ def test_Plot(self): plot.border() - self.assertAlmostEqual(mygrf.linex, - [0.0, 0.071428574621677399, 0.1428571492433548, 0.2142857164144516, - 0.28571429848670959, 0.3571428656578064, 0.4285714328289032, 0.5, - 0.57142859697341919, 0.6428571343421936, 0.71428573131561279, - 0.78571426868438721, 0.8571428656578064, 0.92857140302658081, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 0.92857140302658081, 0.8571428656578064, - 0.78571426868438721, 0.71428573131561279, 0.6428571343421936, - 0.57142859697341919, 0.5, 0.4285714328289032, 0.3571428656578064, - 0.28571429848670959, 0.2142857164144516, 0.1428571492433548, - 0.071428574621677399, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0]) - self.assertAlmostEqual(mygrf.liney, - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.071428574621677399, 0.1428571492433548, 0.2142857164144516, - 0.28571429848670959, 0.3571428656578064, 0.4285714328289032, 0.5, - 0.57142859697341919, 0.6428571343421936, 0.71428573131561279, - 0.78571426868438721, 0.8571428656578064, 0.92857140302658081, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 0.92857140302658081, 0.8571428656578064, 0.78571426868438721, - 0.71428573131561279, 0.6428571343421936, 0.57142859697341919, 0.5, - 0.4285714328289032, 0.3571428656578064, 0.28571429848670959, - 0.2142857164144516, 0.1428571492433548, 0.071428574621677399, 0.0]) + self.assertAlmostEqual( + mygrf.linex, + [ + 0.0, + 0.071428574621677399, + 0.1428571492433548, + 0.2142857164144516, + 0.28571429848670959, + 0.3571428656578064, + 0.4285714328289032, + 0.5, + 0.57142859697341919, + 0.6428571343421936, + 0.71428573131561279, + 0.78571426868438721, + 0.8571428656578064, + 0.92857140302658081, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.92857140302658081, + 0.8571428656578064, + 0.78571426868438721, + 0.71428573131561279, + 0.6428571343421936, + 0.57142859697341919, + 0.5, + 0.4285714328289032, + 0.3571428656578064, + 0.28571429848670959, + 0.2142857164144516, + 0.1428571492433548, + 0.071428574621677399, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + ], + ) + self.assertAlmostEqual( + mygrf.liney, + [ + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.071428574621677399, + 0.1428571492433548, + 0.2142857164144516, + 0.28571429848670959, + 0.3571428656578064, + 0.4285714328289032, + 0.5, + 0.57142859697341919, + 0.6428571343421936, + 0.71428573131561279, + 0.78571426868438721, + 0.8571428656578064, + 0.92857140302658081, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 0.92857140302658081, + 0.8571428656578064, + 0.78571426868438721, + 0.71428573131561279, + 0.6428571343421936, + 0.57142859697341919, + 0.5, + 0.4285714328289032, + 0.3571428656578064, + 0.28571429848670959, + 0.2142857164144516, + 0.1428571492433548, + 0.071428574621677399, + 0.0, + ], + ) self.assertEqual(mygrf.nline, 57) self.assertEqual(mygrf.attr, [4, 4]) self.assertAlmostEqual(mygrf.value, [2.0, 1.0]) @@ -1280,21 +1463,23 @@ def test_Plot(self): mygrf.Reset() plot.grid() - self.assertEqual(mygrf.textt, ['0', '0.3', '0.6', '0.9', '0.4', '0.7', '1', 'Axis 1', 'Axis 2', - '2-d coordinate system']) - self.assertEqual(mygrf.textj, ['TC', 'TC', 'TC', 'TC', 'CR', 'CR', 'CR', 'TC', 'BC', 'BC']) + self.assertEqual( + mygrf.textt, + ["0", "0.3", "0.6", "0.9", "0.4", "0.7", "1", "Axis 1", "Axis 2", "2-d coordinate system"], + ) + self.assertEqual(mygrf.textj, ["TC", "TC", "TC", "TC", "CR", "CR", "CR", "TC", "BC", "BC"]) self.assertEqual(mygrf.ntext, 10) mygrf.Reset() - pin = numpy.array([[0.5, 1., 0.], [0.5, 1., 0.5]]) + pin = numpy.array([[0.5, 1.0, 0.0], [0.5, 1.0, 0.5]]) plot.polycurve(pin) self.assertEqual(mygrf.nline, 29) lbnd, ubnd = plot.boundingbox() self.assertAlmostEqual(lbnd[0], 0) self.assertAlmostEqual(lbnd[1], 0.5) - self.assertAlmostEqual(ubnd[0], 1.) - self.assertAlmostEqual(ubnd[1], 1.) + self.assertAlmostEqual(ubnd[0], 1.0) + self.assertAlmostEqual(ubnd[1], 1.0) plot.Tol = 0.0000001 plot.clip(starlink.Ast.CURRENT, [0.1, 0.1], [0.9, 0.9]) @@ -1358,10 +1543,10 @@ def test_Plot(self): mygrf.Reset() plot.text("Hello", [0.5, 0.5], [0.0, 1.0], "CC") - self.assertEqual(mygrf.textt, ['Hello']) + self.assertEqual(mygrf.textt, ["Hello"]) self.assertEqual(mygrf.textx, [0.5]) self.assertEqual(mygrf.texty, [0.5]) - self.assertEqual(mygrf.textj, ['CC']) + self.assertEqual(mygrf.textj, ["CC"]) self.assertEqual(mygrf.ntext, 1) mygrf.Reset() @@ -1386,7 +1571,7 @@ def test_MatrixMap(self): self.assertTrue(mm.isamatrixmap()) self.assertEqual(mm.Nin, 2) self.assertEqual(mm.Nout, 2) - pin = numpy.array([[1., 2., 3], [0., 1., 2]]) + pin = numpy.array([[1.0, 2.0, 3], [0.0, 1.0, 2]]) pout = mm.tran(pin, False) self.assertAlmostEqual(pout[0][0], -1.0) self.assertAlmostEqual(pout[0][1], -2.0) @@ -1412,8 +1597,7 @@ def test_MatrixMap(self): self.assertAlmostEqual(pout[2][2], -7.0) def test_PolyMap(self): - pm = starlink.Ast.PolyMap([[1.2, 1., 2., 0.], [-0.5, 1., 1., 1.], - [1.0, 2., 0., 1.]]) + pm = starlink.Ast.PolyMap([[1.2, 1.0, 2.0, 0.0], [-0.5, 1.0, 1.0, 1.0], [1.0, 2.0, 0.0, 1.0]]) self.assertIsInstance(pm, starlink.Ast.Object) self.assertIsInstance(pm, starlink.Ast.Mapping) self.assertIsInstance(pm, starlink.Ast.PolyMap) @@ -1422,110 +1606,106 @@ def test_PolyMap(self): self.assertTrue(pm.isapolymap()) self.assertEqual(pm.Nin, 2) self.assertEqual(pm.Nout, 2) - pin = numpy.array([[1., 2., 3], [0., 1., 2]]) + pin = numpy.array([[1.0, 2.0, 3], [0.0, 1.0, 2]]) pout = pm.tran(pin, True) - for (xi, yi, xo, yo) in zip(pin[0], pin[1], pout[0], pout[1]): + for xi, yi, xo, yo in zip(pin[0], pin[1], pout[0], pout[1]): xn = 1.2 * xi * xi - 0.5 * yi * xi yn = yi self.assertAlmostEqual(xn, xo) self.assertAlmostEqual(yn, yo) - pm = starlink.Ast.PolyMap(None, [[1.2, 1., 2., 0.], [-0.5, 1., 1., 1.], - [1.0, 2., 0., 1.]]) + pm = starlink.Ast.PolyMap(None, [[1.2, 1.0, 2.0, 0.0], [-0.5, 1.0, 1.0, 1.0], [1.0, 2.0, 0.0, 1.0]]) self.assertEqual(pm.Nin, 2) self.assertEqual(pm.Nout, 2) pout = pm.tran(pin, False) - for (xi, yi, xo, yo) in zip(pin[0], pin[1], pout[0], pout[1]): + for xi, yi, xo, yo in zip(pin[0], pin[1], pout[0], pout[1]): xn = 1.2 * xi * xi - 0.5 * yi * xi yn = yi self.assertAlmostEqual(xn, xo) self.assertAlmostEqual(yn, yo) - pm = starlink.Ast.PolyMap([[1., 1., 1., 0.], - [1., 1., 0., 1.], - [1., 2., 1., 0.], - [-1., 2., 0., 1.]], - [[0.5, 1., 1., 0.], - [0.5, 1., 0., 1.], - [0.5, 2., 1., 0.], - [-0.5, 2., 0., 1.]]) + pm = starlink.Ast.PolyMap( + [[1.0, 1.0, 1.0, 0.0], [1.0, 1.0, 0.0, 1.0], [1.0, 2.0, 1.0, 0.0], [-1.0, 2.0, 0.0, 1.0]], + [[0.5, 1.0, 1.0, 0.0], [0.5, 1.0, 0.0, 1.0], [0.5, 2.0, 1.0, 0.0], [-0.5, 2.0, 0.0, 1.0]], + ) self.assertEqual(pm.Nin, 2) self.assertEqual(pm.Nout, 2) pout = pm.tran(pin, True) pnew = pm.tran(pout, False) - for (xi, yi, xn, yn) in zip(pin[0], pin[1], pnew[0], pnew[1]): + for xi, yi, xn, yn in zip(pin[0], pin[1], pnew[0], pnew[1]): self.assertAlmostEqual(xn, xi) self.assertAlmostEqual(yn, yi) self.assertEqual(pm.NiterInverse, 4) - self.assertEqual(pm.TolInverse, 1.0E-6) + self.assertEqual(pm.TolInverse, 1.0e-6) - new = pm.polytran(False, 1.0E-8, 0.01, 2, [-1.0, -1.0], [1.0, 1.0]) + new = pm.polytran(False, 1.0e-8, 0.01, 2, [-1.0, -1.0], [1.0, 1.0]) pout = new.tran(pin, True) pnew = new.tran(pout, False) - for (xi, yi, xn, yn) in zip(pin[0], pin[1], pnew[0], pnew[1]): + for xi, yi, xn, yn in zip(pin[0], pin[1], pnew[0], pnew[1]): self.assertAlmostEqual(xn, xi) self.assertAlmostEqual(yn, yi) def test_MathMap(self): with self.assertRaises(TypeError): - mathmap = starlink.Ast.MathMap(2, 1, "r = sqrt( x * x + y * y )", - (1.0, "y=r/sqrt(2)")) + mathmap = starlink.Ast.MathMap(2, 1, "r = sqrt( x * x + y * y )", (1.0, "y=r/sqrt(2)")) with self.assertRaises(TypeError): mathmap = starlink.Ast.MathMap(2, 1, 1, ("x = r/sqrt(2)", "y=r/sqrt(2)")) - mathmap = starlink.Ast.MathMap(2, 1, "r = sqrt( x * x + y * y )", - ("x = r", "y=r")) + mathmap = starlink.Ast.MathMap(2, 1, "r = sqrt( x * x + y * y )", ("x = r", "y=r")) self.assertEqual(mathmap.Class, "MathMap") self.assertIsInstance(mathmap, starlink.Ast.MathMap) self.assertEqual(mathmap.Nin, 2) self.assertEqual(mathmap.Nout, 1) - pin = numpy.array([[1., 2., 3], [0., 1., 2]]) + pin = numpy.array([[1.0, 2.0, 3], [0.0, 1.0, 2]]) pout = mathmap.tran(pin, True) - for (x, y, r) in zip(pin[0], pin[1], pout[0]): + for x, y, r in zip(pin[0], pin[1], pout[0]): rn = math.sqrt(x * x + y * y) self.assertAlmostEqual(rn, r) pin2 = mathmap.tran(pout, False) - for (r, x, y) in zip(pout[0], pin2[0], pin2[1]): + for r, x, y in zip(pout[0], pin2[0], pin2[1]): self.assertAlmostEqual(x, r) self.assertAlmostEqual(y, r) def test_Polygon(self): - polygon = starlink.Ast.Polygon(starlink.Ast.Frame(2), - [[0, 1, 0], [0, 1, 2]]) + polygon = starlink.Ast.Polygon(starlink.Ast.Frame(2), [[0, 1, 0], [0, 1, 2]]) self.assertIsInstance(polygon, starlink.Ast.Polygon) self.assertIsInstance(polygon, starlink.Ast.Region) self.assertIsInstance(polygon, starlink.Ast.Frame) self.assertIsInstance(polygon.getregionframe(), starlink.Ast.Frame) - self.assertTrue(numpy.array_equal(polygon.getregionpoints(), - [[0, 1, 0], [0, 1, 2]])) + self.assertTrue(numpy.array_equal(polygon.getregionpoints(), [[0, 1, 0], [0, 1, 2]])) self.assertEqual(polygon.MeshSize, 200) polygon.MeshSize = 5 self.assertEqual(polygon.MeshSize, 5) - self.assertTrue(numpy.allclose(polygon.getregionmesh(), [[0., 0.5, 1., 0.5, 0., 0., 0.], [ - 0., 0.5, 1., 1.5, 2., 1.333333333333, 0.666666666667]])) + self.assertTrue( + numpy.allclose( + polygon.getregionmesh(), + [ + [0.0, 0.5, 1.0, 0.5, 0.0, 0.0, 0.0], + [0.0, 0.5, 1.0, 1.5, 2.0, 1.333333333333, 0.666666666667], + ], + ) + ) polygon.clear("MeshSize") self.assertEqual(polygon.MeshSize, 200) overlap = polygon.overlap(polygon) self.assertEqual(overlap, 5) - testpolygon = starlink.Ast.Polygon(starlink.Ast.Frame(2), - [[0, 1, 0], [1, 2, 3]]) + testpolygon = starlink.Ast.Polygon(starlink.Ast.Frame(2), [[0, 1, 0], [1, 2, 3]]) overlap = polygon.overlap(testpolygon) self.assertEqual(overlap, 4) array = numpy.array([[0, 0, 0, 0], [0, 1, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]]) - new = starlink.Ast.outline(1, starlink.Ast.EQ, array, [-1, 2], [2, 5], - 0.0, 4, [0, 3], True) - pin = numpy.array([[0., 0., 0], [1.9, 2.1, 4.5]]) + new = starlink.Ast.outline(1, starlink.Ast.EQ, array, [-1, 2], [2, 5], 0.0, 4, [0, 3], True) + pin = numpy.array([[0.0, 0.0, 0], [1.9, 2.1, 4.5]]) pout = new.tran(pin, True) self.assertEqual(pout[0][0], starlink.Ast.BAD) - self.assertEqual(pout[0][1], 0.) + self.assertEqual(pout[0][1], 0.0) self.assertEqual(pout[0][2], starlink.Ast.BAD) self.assertEqual(pout[1][0], starlink.Ast.BAD) self.assertAlmostEqual(pout[1][1], 2.1) @@ -1534,14 +1714,13 @@ def test_Polygon(self): new2 = new.downsize(0, 3) self.assertTrue(new2.isapolygon()) - new = starlink.Ast.convex(1, starlink.Ast.EQ, array, [-1, 2], [2, 5], - True) + new = starlink.Ast.convex(1, starlink.Ast.EQ, array, [-1, 2], [2, 5], True) - pin = numpy.array([[0., 0., 0., 0.], [2.4, 2.6, 3.4, 3.7]]) + pin = numpy.array([[0.0, 0.0, 0.0, 0.0], [2.4, 2.6, 3.4, 3.7]]) pout = new.tran(pin, True) self.assertEqual(pout[0][0], starlink.Ast.BAD) - self.assertEqual(pout[0][1], 0.) - self.assertEqual(pout[0][2], 0.) + self.assertEqual(pout[0][1], 0.0) + self.assertEqual(pout[0][2], 0.0) self.assertEqual(pout[0][3], starlink.Ast.BAD) self.assertEqual(pout[1][0], starlink.Ast.BAD) self.assertEqual(pout[1][1], 2.6) @@ -1549,8 +1728,7 @@ def test_Polygon(self): self.assertEqual(pout[1][3], starlink.Ast.BAD) def test_PointList(self): - pointlist = starlink.Ast.PointList(starlink.Ast.Frame(2), - [[0, 1, 0], [0, 1, 2]]) + pointlist = starlink.Ast.PointList(starlink.Ast.Frame(2), [[0, 1, 0], [0, 1, 2]]) self.assertIsInstance(pointlist, starlink.Ast.PointList) self.assertIsInstance(pointlist, starlink.Ast.Region) self.assertIsInstance(pointlist, starlink.Ast.Frame) @@ -1564,24 +1742,24 @@ def test_Table(self): self.assertIsInstance(table, starlink.Ast.Table) self.assertIsInstance(table, starlink.Ast.KeyMap) with self.assertRaises(starlink.Ast.BADKEY): - table['Fred'] = 123 + table["Fred"] = 123 dims = [5, 2] - table.addcolumn('Fred', starlink.Ast.DOUBLETYPE, dims) + table.addcolumn("Fred", starlink.Ast.DOUBLETYPE, dims) self.assertEqual(table.Ncolumn, 1) - self.assertEqual(table.columnname(1), 'FRED') - self.assertEqual(int(table.get('ColumnType(Fred)')), starlink.Ast.DOUBLETYPE) - dims = table.columnshape('Fred') + self.assertEqual(table.columnname(1), "FRED") + self.assertEqual(int(table.get("ColumnType(Fred)")), starlink.Ast.DOUBLETYPE) + dims = table.columnshape("Fred") self.assertEqual(dims[0], 5) self.assertEqual(dims[1], 2) - self.assertEqual(table.get('ColumnUnit(Fred)'), '') + self.assertEqual(table.get("ColumnUnit(Fred)"), "") with self.assertRaises(starlink.Ast.BADTYP): - table['Fred(2)'] = 123 + table["Fred(2)"] = 123 with self.assertRaises(starlink.Ast.BADTYP): - table['Fred(2)'] = 123.0 - table['Fred(2)'] = numpy.linspace(1, 10, 10) - self.assertEqual(table.columnlength('Fred'), 10) - self.assertEqual(table.columnndim('Fred'), 2) - self.assertEqual(table.columnunit('Fred'), '') + table["Fred(2)"] = 123.0 + table["Fred(2)"] = numpy.linspace(1, 10, 10) + self.assertEqual(table.columnlength("Fred"), 10) + self.assertEqual(table.columnndim("Fred"), 2) + self.assertEqual(table.columnunit("Fred"), "") def test_FitsTable(self): table = starlink.Ast.FitsTable() @@ -1593,7 +1771,7 @@ def test_FitsTable(self): tables = fc.gettables() self.assertEqual(len(tables), 1) keys = tables.keys() - self.assertEqual(keys[0], 'Fred') + self.assertEqual(keys[0], "Fred") def test_Moc(self): moc = starlink.Ast.Moc("maxorder=18") @@ -1603,124 +1781,121 @@ def test_Moc(self): moc.MinOrder = 11 self.assertEqual(moc.MinOrder, 11) - reg1 = starlink.Ast.Circle(starlink.Ast.SkyFrame(), 1, - [1, 1], 2.0E-4 ) - moc.addregion( reg1 ) - self.assertAlmostEqual(moc.MocArea, 1.485, delta=1.0E-3) + reg1 = starlink.Ast.Circle(starlink.Ast.SkyFrame(), 1, [1, 1], 2.0e-4) + moc.addregion(reg1) + self.assertAlmostEqual(moc.MocArea, 1.485, delta=1.0e-3) data = moc.getmocdata() - self.assertEqual( len(data.shape), 1 ) - self.assertEqual( data.shape[0], 385 ) - self.assertEqual( data.dtype, numpy.int64 ) + self.assertEqual(len(data.shape), 1) + self.assertEqual(data.shape[0], 385) + self.assertEqual(data.dtype, numpy.int64) moc2 = starlink.Ast.Moc("maxorder=18") moc2.addmocdata(data) - self.assertEqual( moc.overlap(moc2), 5 ) + self.assertEqual(moc.overlap(moc2), 5) moc = starlink.Ast.Moc("maxorder=8,minorder=4") centre = [3.1415927, 0.75] sf = starlink.Ast.SkyFrame() - reg1 = starlink.Ast.Circle(sf, 1, centre, 0.5 ) - moc.addregion( reg1 ) - self.assertAlmostEqual(moc.MaxRes, 824.5167, delta=1.0E-4) + reg1 = starlink.Ast.Circle(sf, 1, centre, 0.5) + moc.addregion(reg1) + self.assertAlmostEqual(moc.MaxRes, 824.5167, delta=1.0e-4) lbnd, ubnd = moc.getregionbounds() - self.assertAlmostEqual(lbnd[0], 2.4235144, delta=1E-6 ) - self.assertAlmostEqual(ubnd[0], 3.8596708, delta=1E-6 ) - self.assertAlmostEqual(lbnd[1], 0.2499916, delta=1E-6 ) - self.assertAlmostEqual(ubnd[1], 1.2504847, delta=1E-6 ) - - mesh = moc.getregionmesh( 1 ) - self.assertEqual( len(mesh.shape), 2 ) - self.assertEqual( mesh.shape[0], 2 ) - self.assertEqual( mesh.shape[1], 868 ) - mxerr = math.radians( 0.7*824.5167/3600.0 ) + self.assertAlmostEqual(lbnd[0], 2.4235144, delta=1e-6) + self.assertAlmostEqual(ubnd[0], 3.8596708, delta=1e-6) + self.assertAlmostEqual(lbnd[1], 0.2499916, delta=1e-6) + self.assertAlmostEqual(ubnd[1], 1.2504847, delta=1e-6) + + mesh = moc.getregionmesh(1) + self.assertEqual(len(mesh.shape), 2) + self.assertEqual(mesh.shape[0], 2) + self.assertEqual(mesh.shape[1], 868) + mxerr = math.radians(0.7 * 824.5167 / 3600.0) for i in range(868): - point = [ mesh[0][i], mesh[1][i] ] - self.assertAlmostEqual( sf.distance( centre, point ), 0.5, delta=mxerr ) - self.assertEqual( moc.MocType, 4 ) - self.assertEqual( moc.MocLength, 832 ) + point = [mesh[0][i], mesh[1][i]] + self.assertAlmostEqual(sf.distance(centre, point), 0.5, delta=mxerr) + self.assertEqual(moc.MocType, 4) + self.assertEqual(moc.MocLength, 832) fc = moc.getmocheader() self.assertEqual(fc["NAXIS1"], 4) self.assertEqual(fc["NAXIS2"], 832) - self.assertEqual(fc["TFORM1"], '1J') + self.assertEqual(fc["TFORM1"], "1J") self.assertEqual(fc["MOCORDER"], 8) - image = numpy.empty([100,100],order='F') + image = numpy.empty([100, 100], order="F") for j in range(100): - dy = j + 1 - 50.5 - dy2 = dy*dy - for i in range(100): - dx = i + 1 - 50.5 - image[j][i] = math.sqrt( dx*dx + dy2 ) + dy = j + 1 - 50.5 + dy2 = dy * dy + for i in range(100): + dx = i + 1 - 50.5 + image[j][i] = math.sqrt(dx * dx + dy2) fc.emptyfits() - fc['CRVAL1'] = 35.0 - fc['CRVAL2'] = 55.0 - fc['CRPIX1'] = 50.5 - fc['CRPIX2'] = 50.5 - fc['CDELT1'] = -0.01 - fc['CDELT2'] = 0.01 - fc['CTYPE1'] = 'RA---TAN' - fc['CTYPE2'] = 'DEC--TAN' - fc['CRVAL3'] = -22.9 - fc['CRPIX3'] = 1.0 - fc['CDELT3'] = 1.27 - fc['CTYPE3'] = 'VRAD ' - fc['CUNIT3'] = 'km/s ' + fc["CRVAL1"] = 35.0 + fc["CRVAL2"] = 55.0 + fc["CRPIX1"] = 50.5 + fc["CRPIX2"] = 50.5 + fc["CDELT1"] = -0.01 + fc["CDELT2"] = 0.01 + fc["CTYPE1"] = "RA---TAN" + fc["CTYPE2"] = "DEC--TAN" + fc["CRVAL3"] = -22.9 + fc["CRPIX3"] = 1.0 + fc["CDELT3"] = 1.27 + fc["CTYPE3"] = "VRAD " + fc["CUNIT3"] = "km/s " wcs = fc.read() moc = starlink.Ast.Moc() - moc.addpixelmask(image,starlink.Ast.LT,10,0.0,wcs,0) - self.assertAlmostEqual(moc.MaxRes, 12.883, delta=1.0E-3) + moc.addpixelmask(image, starlink.Ast.LT, 10, 0.0, wcs, 0) + self.assertAlmostEqual(moc.MaxRes, 12.883, delta=1.0e-3) - mesh = moc.getregionmesh( 1 ) - self.assertEqual( mesh.shape[1], 294 ) + mesh = moc.getregionmesh(1) + self.assertEqual(mesh.shape[1], 294) - centre = [ math.radians( 35 ), math.radians( 55 ) ] - mxerr = math.radians( 0.01 ) + centre = [math.radians(35), math.radians(55)] + mxerr = math.radians(0.01) for i in range(mesh.shape[1]): - point = [ mesh[0][i], mesh[1][i] ] - self.assertAlmostEqual( sf.distance( centre, point ), 1.745E-3, delta=mxerr ) - + point = [mesh[0][i], mesh[1][i]] + self.assertAlmostEqual(sf.distance(centre, point), 1.745e-3, delta=mxerr) centre = [0.0, 1.57] - reg1 = starlink.Ast.Circle(sf, 1, centre, 0.3 ) + reg1 = starlink.Ast.Circle(sf, 1, centre, 0.3) moc = starlink.Ast.Moc("maxorder=8,minorder=4") - moc.addregion( reg1 ) + moc.addregion(reg1) moc2 = starlink.Ast.Moc() - moc2.addregion( moc ) - self.assertEqual( moc.overlap(moc2), 5 ) + moc2.addregion(moc) + self.assertEqual(moc.overlap(moc2), 5) - reg2 = starlink.Ast.Circle(sf, 1, centre, 0.2 ) + reg2 = starlink.Ast.Circle(sf, 1, centre, 0.2) reg2.negate() moc2 = starlink.Ast.Moc("maxorder=9,minorder=4") - moc2.addregion( reg2 ) + moc2.addregion(reg2) - moc.addregion( moc2, starlink.Ast.AND ) - self.assertAlmostEqual(moc.MocArea, 1.843466E6, delta=1.0 ) + moc.addregion(moc2, starlink.Ast.AND) + self.assertAlmostEqual(moc.MocArea, 1.843466e6, delta=1.0) moc2 = starlink.Ast.Moc("maxorder=7,minorder=4") - moc2.addregion( reg2 ) + moc2.addregion(reg2) - moc.addregion(moc2, starlink.Ast.AND ) - self.assertAlmostEqual(moc.MocArea, 1.803054E6, delta=1.0 ) + moc.addregion(moc2, starlink.Ast.AND) + self.assertAlmostEqual(moc.MocArea, 1.803054e6, delta=1.0) moc3 = starlink.Ast.Moc() moc3.MaxOrder = moc.MaxOrder for i in range(moc.MocLength): - (order,npix) = moc.getcell( i ) - self.assertTrue( moc.testcell( order, npix, False ) ) - moc3.addcell( order, npix ) + (order, npix) = moc.getcell(i) + self.assertTrue(moc.testcell(order, npix, False)) + moc3.addcell(order, npix) - self.assertEqual( moc.overlap(moc3), 5 ) - self.assertFalse( moc.testcell( 8, 123456, False ) ) + self.assertEqual(moc.overlap(moc3), 5) + self.assertFalse(moc.testcell(8, 123456, False)) moc4 = starlink.Ast.Moc() - json = moc4.addmocstring( '1/1-2,4 2/12-14,21,23,25 8/' ) - self.assertFalse( json ) - self.assertEqual( moc4.getmocstring( True ), - '{"1":[1,2,4],"2":[12,13,14,21,23,25],"8":[]}' ) + json = moc4.addmocstring("1/1-2,4 2/12-14,21,23,25 8/") + self.assertFalse(json) + self.assertEqual(moc4.getmocstring(True), '{"1":[1,2,4],"2":[12,13,14,21,23,25],"8":[]}') def test_MocChan(self): ss = TextStream() @@ -1739,21 +1914,26 @@ def test_MocChan(self): self.assertEqual(obj.Class, "Moc") ss.reset() - n = ch.write( obj ) + n = ch.write(obj) self.assertEqual(n, 1) b = ss.get() - self.assertEqual(a, b[0] ) + self.assertEqual(a, b[0]) def test_ChebyMap(self): - lbnd = [0.,0.] - ubnd = [10.,10.] - pm = starlink.Ast.ChebyMap([[ 1.0, 1.0, 0.0, 0.0 ], - [ -2.0, 1.0, 1.0, 2.0 ], - [ 1.0, 1.0, 0.0, 1.0 ], - [ 1.5, 2.0, 0.0, 0.0 ], - [ -2.5, 2.0, 1.0, 2.0 ]], - lbnd, ubnd ) + lbnd = [0.0, 0.0] + ubnd = [10.0, 10.0] + pm = starlink.Ast.ChebyMap( + [ + [1.0, 1.0, 0.0, 0.0], + [-2.0, 1.0, 1.0, 2.0], + [1.0, 1.0, 0.0, 1.0], + [1.5, 2.0, 0.0, 0.0], + [-2.5, 2.0, 1.0, 2.0], + ], + lbnd, + ubnd, + ) self.assertIsInstance(pm, starlink.Ast.Object) self.assertIsInstance(pm, starlink.Ast.Mapping) self.assertIsInstance(pm, starlink.Ast.PolyMap) @@ -1765,24 +1945,21 @@ def test_ChebyMap(self): self.assertEqual(pm.Nin, 2) self.assertEqual(pm.Nout, 2) - pin = numpy.array([[0.0,2.0,6.0,10.0],[2.0,5.0,8.0,0.0]]) + pin = numpy.array([[0.0, 2.0, 6.0, 10.0], [2.0, 5.0, 8.0, 0.0]]) pout = pm.tran(pin, True) - for (xin, yin, xo, yo) in zip(pin[0], pin[1], pout[0], pout[1]): - xi = 2.0*( xin - lbnd[0] )/( ubnd[0] - lbnd[0] ) - 1.0 - yi = 2.0*( yin - lbnd[1] )/( ubnd[1] - lbnd[1] ) - 1.0 - xv = 1 - 2*xi*(2*yi*yi - 1) + yi - yv = 1.5 - 2.5*xi*(2*yi*yi - 1) - self.assertAlmostEqual(xv, xo) - self.assertAlmostEqual(yv, yo) - - - + for xin, yin, xo, yo in zip(pin[0], pin[1], pout[0], pout[1]): + xi = 2.0 * (xin - lbnd[0]) / (ubnd[0] - lbnd[0]) - 1.0 + yi = 2.0 * (yin - lbnd[1]) / (ubnd[1] - lbnd[1]) - 1.0 + xv = 1 - 2 * xi * (2 * yi * yi - 1) + yi + yv = 1.5 - 2.5 * xi * (2 * yi * yi - 1) + self.assertAlmostEqual(xv, xo) + self.assertAlmostEqual(yv, yo) if __name__ == "__main__": # starlink.Ast.watchmemory(10914) # unittest.main() - print( "Testing pyast version {}\n".format(starlink.Ast.__version__) ) + print("Testing pyast version {}\n".format(starlink.Ast.__version__)) suite = unittest.TestLoader().loadTestsFromTestCase(TestAst) unittest.TextTestRunner(verbosity=2).run(suite) starlink.Ast.activememory("AST memory block still active") diff --git a/starlink/ast/test/test_atl.py b/starlink/ast/test/test_atl.py index 7b8b5e3..eb3994d 100644 --- a/starlink/ast/test/test_atl.py +++ b/starlink/ast/test/test_atl.py @@ -4,16 +4,17 @@ from astropy.io import fits as pyfits except ImportError: import pyfits -import starlink.Atl as Atl -import starlink.Ast as Ast + import matplotlib.pyplot +import starlink.Ast as Ast +import starlink.Atl as Atl + # Use pyfits to open a test files file -ffile = pyfits.open('starlink/ast/test/cobe.fit') +ffile = pyfits.open("starlink/ast/test/cobe.fit") # Use matplotlib to plot an annotated grid of the WCS coords -Atl.plotfitswcs(matplotlib.pyplot.figure(figsize=(8, 8)).add_subplot(111), - [0.1, 0.1, 0.9, 0.9], ffile) +Atl.plotfitswcs(matplotlib.pyplot.figure(figsize=(8, 8)).add_subplot(111), [0.1, 0.1, 0.9, 0.9], ffile) matplotlib.pyplot.show() # Create a FitsChan telling it to use the pyfits primary hdu as the diff --git a/starlink/ast/test/testplot.py b/starlink/ast/test/testplot.py index 35ef2d6..9e7ca9a 100644 --- a/starlink/ast/test/testplot.py +++ b/starlink/ast/test/testplot.py @@ -1,4 +1,5 @@ import matplotlib.pyplot as plt + import starlink.Ast import starlink.Grf @@ -54,7 +55,7 @@ # Change the definition of font 0 within the grf module, and plot # another string, still using font 0. -grf.fonts[0] = {"family": 'monospace', "style": 'italic'} +grf.fonts[0] = {"family": "monospace", "style": "italic"} plot.text("Hello", [0, 65], [-1, 1], "CC") # Display everything. diff --git a/tools/make_attributes.py b/tools/make_attributes.py index df0652f..2276b55 100644 --- a/tools/make_attributes.py +++ b/tools/make_attributes.py @@ -23,14 +23,14 @@ def make_attributes(dirname=None): # The hard-wired maximum number of dimensions supported by pyast. mxdim = 40 -# Open the input file. + # Open the input file. file = "attributes.desc" if dirname is not None: file = os.path.join(dirname, file) infile = open(file, "r") -# Read the input file. + # Read the input file. for line in infile: # Ignore blank lines or comment lines @@ -38,24 +38,24 @@ def make_attributes(dirname=None): if len(line) == 0 or line.startswith("#"): continue -# Split the line into comma-separated fields + # Split the line into comma-separated fields (classname, attname, readonly, atype, desc, maxindex, minindex, items) = line.split(",") -# Convert strings to numerical values + # Convert strings to numerical values minindex = int(minindex) -# Initialise lists + # Initialise lists att_decs = list() att_descs = list() -# Convert the fields to more useful types. + # Convert the fields to more useful types. items = items.split() if maxindex == "MXDIM": maxindex = mxdim else: maxindex = int(maxindex) -# Loop over all indices for multi-valued attributes + # Loop over all indices for multi-valued attributes for i in range(minindex, maxindex + 1): # Loop over all keys for multi-valued attributes @@ -69,41 +69,49 @@ def make_attributes(dirname=None): else: aname += "_" + str(i) -# Form the C macro invocation that defines the attribute and append it -# to the list. + # Form the C macro invocation that defines the attribute and append it + # to the list. mac = "MAKE_GET" + readonly + atype + "(" + classname + "," + aname + ")" att_decs.append(mac) -# Form the attribute description to store in the Python TypeObject. - mac = "DEFATT(" + aname + ", \"" + desc + "\")," + # Form the attribute description to store in the Python TypeObject. + mac = "DEFATT(" + aname + ', "' + desc + '"),' att_descs.append(mac) -# Multi-valued attributes can also (usually) be used without any index -# of key. So add an unqualified attribute to the lists. + # Multi-valued attributes can also (usually) be used without any index + # of key. So add an unqualified attribute to the lists. mac = "MAKE_GET" + readonly + atype + "(" + classname + "," + attname + ")" att_decs.append(mac) - mac = "DEFATT(" + attname + ", \"" + desc + "\")," + mac = "DEFATT(" + attname + ', "' + desc + '"),' att_descs.append(mac) -# Open the output def file + # Open the output def file cfilename = attname + "_def.c" if dirname is not None: cfilename = os.path.join(dirname, cfilename) cfile = open(cfilename, "w") -# Write out a prologue for the C file - print(r"""/* + # Write out a prologue for the C file + print( + r"""/* * Name: -* """ + attname + "_def.c" + r""" +* """ + + attname + + "_def.c" + + r""" * Purpose: -* Declare and define the Python accessor methods for the """ + attname + r""" +* Declare and define the Python accessor methods for the """ + + attname + + r""" * attribute. * Description: * This file uses the macros defined in pyast.h to define and declare * methods for accessing all the values within the multi-valued AST -* attribute """ + attname + r""". +* attribute """ + + attname + + r""". * Notes: * - This file is generated automatically by the "make_attributes.py" @@ -111,31 +119,41 @@ def make_attributes(dirname=None): * attributes.desc which is used as input by "make_attributes.py". */ -""", file=cfile) +""", + file=cfile, + ) -# Write out the attribute declarations, then close the file. + # Write out the attribute declarations, then close the file. for att in att_decs: print(att, file=cfile) cfile.close() -# Open the output desc file + # Open the output desc file cfilename = attname + "_desc.c" if dirname is not None: cfilename = os.path.join(dirname, cfilename) cfile = open(cfilename, "w") -# Write out a prologue for the C file - print(r"""/* + # Write out a prologue for the C file + print( + r"""/* * Name: -* """ + attname + "_desc.c" + r""" +* """ + + attname + + "_desc.c" + + r""" * Purpose: * Add entries to the array of Python attribute accessors describing -* the """ + attname + r""" attribute. +* the """ + + attname + + r""" attribute. * Description: * This file uses the macros defined in pyast.h to create a description -* of the multi-valued AST attribute """ + attname + r""" for inclusion in +* of the multi-valued AST attribute """ + + attname + + r""" for inclusion in * the array of attribute getters and setters store in the Python * TypeObject for the class. @@ -145,14 +163,16 @@ def make_attributes(dirname=None): * attributes.desc which is used as input by "make_attributes.py". */ -""", file=cfile) +""", + file=cfile, + ) -# Write out the attribute dedriptions, then close the file. + # Write out the attribute dedriptions, then close the file. for att in att_descs: print(" " + att, file=cfile) cfile.close() -# Close the input file. + # Close the input file. infile.close() diff --git a/tools/make_exceptions.py b/tools/make_exceptions.py index cfcc742..e44062a 100644 --- a/tools/make_exceptions.py +++ b/tools/make_exceptions.py @@ -17,14 +17,14 @@ def make_exceptions(dirname=None): - if 'AST_SOURCE' not in os.environ: + if "AST_SOURCE" not in os.environ: print("Please set AST_SOURCE environment variable to point to the AST source code directory") exit(1) # ensure that we have the error codes file - errfile = os.path.join(os.environ['AST_SOURCE'], "ast_err.h") + errfile = os.path.join(os.environ["AST_SOURCE"], "ast_err.h") if not os.path.exists(errfile): - print("Could not find the ast_err.h file in directory " + os.environ['AST_SOURCE']) + print("Could not find the ast_err.h file in directory " + os.environ["AST_SOURCE"]) exit(1) # Open an output C file @@ -35,7 +35,8 @@ def make_exceptions(dirname=None): cfile = open(cfilename, "w") # Need a C header - print(r"""/* + print( + r"""/* * Name: * exceptions.c @@ -63,7 +64,9 @@ def make_exceptions(dirname=None): static PyObject *AstError_err; /* For each AST error code, declare a static variable to hold an instance - of the corresponding Python Exception. */""", file=cfile) + of the corresponding Python Exception. */""", + file=cfile, + ) # Now read the ast_err.h file and create extract all the error codes # Note that AST__3DFSET is not currently supported because a @@ -83,7 +86,8 @@ def make_exceptions(dirname=None): for code in errcodes: print("static PyObject *{0}_err;".format(code), file=cfile) - print(r""" + print( + r""" /* Defines a function that creates a Python Exception object for each AST error code, and uses them to initialises the above static variables. It reurns 1 if successful, and zero @@ -98,15 +102,20 @@ def make_exceptions(dirname=None): if( !( AstError_err = PyErr_NewException("Ast.AstError", NULL, NULL))) return 0; PyDict_SetItemString( dict, "AstError", AstError_err ); -/* Now create an instance of each derived AST exception class. */""", file=cfile) +/* Now create an instance of each derived AST exception class. */""", + file=cfile, + ) for code in errcodes: - print(' if( !({0}_err = PyErr_NewException("Ast.{0}", AstError_err, NULL))) return 0;'.format(code), - file=cfile) + print( + ' if( !({0}_err = PyErr_NewException("Ast.{0}", AstError_err, NULL))) return 0;'.format(code), + file=cfile, + ) print(' PyDict_SetItemString( dict, "{0}", {0}_err );'.format(code), file=cfile) print(" ", file=cfile) - print(r""" return 1; + print( + r""" return 1; } @@ -166,7 +175,9 @@ def make_exceptions(dirname=None): return; } -/* If no exception has already occurred, raise an appropriate AST exception now. */""", file=cfile) +/* If no exception has already occurred, raise an appropriate AST exception now. */""", + file=cfile, + ) first = True for code in errcodes: @@ -177,14 +188,17 @@ def make_exceptions(dirname=None): print(" }} else if( status_value == AST__{0} ) {{".format(code), file=cfile) print(" PyErr_SetString( {0}_err, message );".format(code), file=cfile) - print(""" } else { + print( + """ } else { PyErr_SetString( AstError_err, message ); } /* restore the original AST status value. */ astSetStatus( lstat ); } -""", file=cfile) +""", + file=cfile, + ) cfile.close() From 57699e8037f23815273682717bc4b144d8c9512c Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Sat, 17 Aug 2024 17:22:18 -0700 Subject: [PATCH 2/8] Configure flake8 to be compatible with black --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index c836869..5ce39eb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,3 @@ [flake8] +ignore = W503, E203, E704 max-line-length = 110 From 83f5593e8175f9f82b17b055d7b65b215c79040e Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Sun, 18 Aug 2024 16:11:05 -0700 Subject: [PATCH 3/8] Start work needed for numpy 2 and Python 3.13 distutils is no longer usable. --- setup.py | 50 +++--- starlink/Atl.py | 4 +- starlink/ast/Ast.c | 404 ++++++++++++++++++++++----------------------- 3 files changed, 222 insertions(+), 236 deletions(-) diff --git a/setup.py b/setup.py index 8983e00..00a2771 100644 --- a/setup.py +++ b/setup.py @@ -5,8 +5,7 @@ import re import sys import tarfile -from distutils import ccompiler -from distutils.core import Extension, setup +from setuptools import Distribution, Extension, setup from textwrap import dedent import numpy @@ -14,6 +13,22 @@ from tools import make_attributes, make_exceptions +def get_compiler(): + """Get the compiler. + + distutils.ccompiler is no longer directly available. + """ + build_ext = Distribution().get_command_obj("build_ext") + build_ext.finalize_options() + # register an extension to ensure a compiler is created + build_ext.extensions = [Extension("ignored", ["ignored.c"])] + # disable building fake extensions + build_ext.build_extensions = lambda: None + # run to populate self.compiler + build_ext.run() + return build_ext.compiler + + def get_version(): result = None with open("starlink/ast/Ast.c") as f: @@ -31,11 +46,8 @@ def check_libyaml(): """check if the C module can be build by trying to compile a small program against the libyaml development library""" - import distutils.ccompiler - import distutils.sysconfig import shutil import tempfile - from distutils.errors import CompileError, LinkError libraries = ["yaml"] @@ -59,9 +71,7 @@ def check_libyaml(): fp.write(c_code) # and try to compile it - compiler = distutils.ccompiler.new_compiler() - assert isinstance(compiler, distutils.ccompiler.CCompiler) - distutils.sysconfig.customize_compiler(compiler) + compiler = get_compiler() try: compiler.link_executable( @@ -69,11 +79,8 @@ def check_libyaml(): bin_file_name, libraries=libraries, ) - except CompileError: - print("libyaml compile error") - ret_val = False - except LinkError: - print("libyaml link error") + except Exception as e: + print(f"libyaml compilation error: {e}") ret_val = False else: ret_val = True @@ -456,16 +463,13 @@ def check_libyaml(): # Test the compiler define_macros = [] -compiler = ccompiler.new_compiler() +compiler = get_compiler() if compiler.has_function("strtok_r"): define_macros.append(("HAVE_STRTOK_R", "1")) if compiler.has_function("strerror_r"): define_macros.append(("HAVE_STRERROR_R", "1")) -if compiler.has_function("isfinite"): - define_macros.append(("HAVE_DECL_ISFINITE", "1")) - if check_libyaml(): define_macros.append(("YAML", "1")) extra_link_args.append("-lyaml") @@ -476,6 +480,9 @@ def check_libyaml(): define_macros.append(("SIZEOF_LONG", ctypes.sizeof(ctypes.c_long))) define_macros.append(("SIZEOF_LONG_LONG", ctypes.sizeof(ctypes.c_longlong))) +# isfinite is from C99 so we can now assume this exists. +define_macros.append(("HAVE_DECL_ISFINITE", "1")) + # Assume we have isnan() available and assume we have a working sscanf # configure would test for these but we no longer run configure define_macros.append(("HAVE_DECL_ISNAN", "1")) @@ -487,13 +494,8 @@ def check_libyaml(): # name clashes when loaded alongside libast itself (eg from pyndf) symbol_list = "public_symbols.txt" if sys.platform.startswith("darwin"): - symfile = open(symbol_list, "w") - if sys.version_info[0] > 2: - symname = "_PyInit_Ast" - else: - symname = "_initAst" - print(symname, file=symfile) - symfile.close() + with open(symbol_list, "w") as symfile: + print("_PyInit_Ast", file=symfile) extra_link_args.append("-exported_symbols_list") extra_link_args.append(symbol_list) diff --git a/starlink/Atl.py b/starlink/Atl.py index 7c56146..a040c5a 100644 --- a/starlink/Atl.py +++ b/starlink/Atl.py @@ -1,4 +1,4 @@ -from distutils.version import LooseVersion +from packaging.version import parse import starlink.Ast as Ast @@ -116,7 +116,7 @@ def __init__(self, hdu, clear=True): # Save a flag indicating if the version of pyfits is 3.1.0 or later # (some of the earlier API was deprecated at 3.1.0). if _using_pyfits: - self.pre_pyfits_3_1_0 = LooseVersion(pyfits.__version__) < LooseVersion("3.1.0") + self.pre_pyfits_3_1_0 = parse(pyfits.__version__) < parse("3.1.0") # ----------------------------------------------------------------- def astsource(self): diff --git a/starlink/ast/Ast.c b/starlink/ast/Ast.c index f55422a..e0227bf 100644 --- a/starlink/ast/Ast.c +++ b/starlink/ast/Ast.c @@ -8,27 +8,11 @@ #include "src/grf.h" /* Define macros for things that changed between Python V2.7 and V3.2 */ -#if PY_MAJOR_VERSION >= 3 #define PYTYPEOBJECT_HEAD PyVarObject_HEAD_INIT(NULL,0) #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void) #define RETURN(value) return value #define STRING_CHECK(value) PyUnicode_Check(value) #define LONG_CHECK(value) PyLong_Check(value) -#else -#define PYTYPEOBJECT_HEAD PyObject_HEAD_INIT(NULL) 0, -#define MOD_INIT(name) PyMODINIT_FUNC init##name(void) -#define RETURN(value) return -#define STRING_CHECK(value) (PyString_Check(value)||PyUnicode_Check(value)) -#define LONG_CHECK(value) (PyInt_Check(value)||PyLong_Check(value)) - -/* A pointer to the python module structure. This is needed to provide - support for Python V2.7, since in Python V2.7 module function do not - receive a pointer to the module object as their first argument (i.e. the - "self" argument for module functions is always NULL in V2.7). */ -static PyObject *pyast_module = NULL; - -#endif - /* Define the name of the package and module, and initialise the current class and method name so that we have something to undef. */ @@ -63,46 +47,46 @@ const char *GetObjectType( PyObject *o ); static const char * numpydtype2str ( int dtype ) { const char * retval; switch (dtype) { - case PyArray_DOUBLE: + case NPY_DOUBLE: retval = "double"; break; - case PyArray_FLOAT: + case NPY_FLOAT: retval = "float"; break; - case PyArray_INT: + case NPY_INT: retval = "int"; break; - case PyArray_UINT: + case NPY_UINT: retval = "unsigned int"; break; - case PyArray_BYTE: + case NPY_BYTE: retval = "byte"; break; - case PyArray_UBYTE: + case NPY_UBYTE: retval = "unsigned byte"; break; - case PyArray_SHORT: + case NPY_SHORT: retval = "short"; break; - case PyArray_USHORT: + case NPY_USHORT: retval = "unsigned short"; break; - case PyArray_LONG: + case NPY_LONG: retval = "long"; break; - case PyArray_ULONG: + case NPY_ULONG: retval = "unsigned long"; break; - case PyArray_LONGLONG: + case NPY_LONGLONG: retval = "long long"; break; - case PyArray_ULONGLONG: + case NPY_ULONGLONG: retval = "unsigned long long"; break; - case PyArray_CFLOAT: + case NPY_CFLOAT: retval = "complex float"; break; - case PyArray_CDOUBLE: + case NPY_CDOUBLE: retval = "complex double"; break; default: @@ -761,7 +745,7 @@ static PyObject *Mapping_linearapprox( Mapping *self, PyObject *args ) { ubnd = GetArray1D( ubnd_object, &ncoord_in, "ubnd", NAME ); if( lbnd && ubnd ) { dims[ 0 ] = ( ncoord_in + 1 )*ncoord_out; - fit = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + fit = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if( fit ) { islinear = astLinearApprox( THIS, (const double *)lbnd->data, (const double *)ubnd->data, tol, @@ -814,8 +798,8 @@ static PyObject *Mapping_mapbox( Mapping *self, PyObject *args ) { ubnd_in = GetArray1D( ubnd_in_object, &ncoord_in, "ubnd_in", NAME ); if( lbnd_in && ubnd_in ) { dims[ 0 ] = ncoord_in; - xl = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); - xu = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + xl = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); + xu = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if( xl && xu ) { astMapBox( THIS, (const double *)lbnd_in->data, (const double *)ubnd_in->data, forward, coord_out, @@ -897,7 +881,7 @@ static PyObject *Mapping_mapmerge( Mapping *self, PyObject *args ) { maplist_object = PyList_New( (Py_ssize_t) nmap ); dims[ 0 ] = nmap; - invlist_out = PyArray_SimpleNew( 1, dims, PyArray_INT ); + invlist_out = PyArray_SimpleNew( 1, dims, NPY_INT ); if( astOK && maplist_object && invlist_out ) { pi = ((int *)invlist_out->data); for( i = 0; i < nmap; i++ ) { @@ -938,11 +922,11 @@ static PyObject *Mapping_mapsplit( Mapping *self, PyObject *args ) { if( PyArg_ParseTuple( args, "O:" NAME, &in_object ) && astOK ) { in = (PyArrayObject *) PyArray_ContiguousFromAny( in_object, - PyArray_INT, 0, 100); + NPY_INT, 0, 100); if( in ) { nin = PyArray_Size( (PyObject *) in ); dims[ 0 ] = astGetI( THIS, "Nout" ); - out = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_INT ); + out = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_INT ); if( out ) { memset( out->data, 0, dims[ 0 ]*sizeof( int ) ); @@ -996,7 +980,7 @@ static PyObject *Mapping_quadapprox( Mapping *self, PyObject *args ) { ubnd = GetArray1D( ubnd_object, &ncoord_in, "ubnd", NAME ); if( lbnd && ubnd ) { dims[ 0 ] = 6*ncoord_out; - fit = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + fit = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if( fit ) { isquad = astQuadApprox( THIS, (const double *)lbnd->data, (const double *)ubnd->data, nx, ny, @@ -1116,14 +1100,14 @@ static PyObject *Mapping_rebin( Mapping *self, PyObject *args ) { } else { type = ((PyArrayObject*) in_object)->descr->type_num; - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { format[ 10 ] = 'd'; pbadval = &badval_d; - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { format[ 10 ] = 'f'; pbadval = &badval_f; - } else if( type == PyArray_INT || - (type == PyArray_LONG && sizeof(int) == sizeof(long))) { + } else if( type == NPY_INT || + (type == NPY_LONG && sizeof(int) == sizeof(long))) { format[ 10 ] = 'i'; pbadval = &badval_i; } else { @@ -1194,7 +1178,7 @@ static PyObject *Mapping_rebin( Mapping *self, PyObject *args ) { if( out && ( ( in_var && out_var ) || !in_var ) ) { - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { astRebinD( THIS, wlim, ncoord_in, (const int *)lbnd_in->data, (const int *)ubnd_in->data, (const double *)in->data, (in_var ? (const double *)in_var->data : NULL), @@ -1204,7 +1188,7 @@ static PyObject *Mapping_rebin( Mapping *self, PyObject *args ) { (const int *)lbnd->data, (const int *)ubnd->data, (double *)out->data, (out_var ? (double *)out_var->data : NULL ) ); - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { astRebinF( THIS, wlim, ncoord_in, (const int *)lbnd_in->data, (const int *)ubnd_in->data, (const float *)in->data, (in_var ? (const float *)in_var->data : NULL), @@ -1326,14 +1310,14 @@ static PyObject *Mapping_rebinseq( Mapping *self, PyObject *args ) { "an array object" ); } else { type = ((PyArrayObject*) in_object)->descr->type_num; - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { format[ 10 ] = 'd'; pbadval = &badval_d; - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { format[ 10 ] = 'f'; pbadval = &badval_f; - } else if( type == PyArray_INT || - (type == PyArray_LONG && sizeof(int) == sizeof(long))) { + } else if( type == NPY_INT || + (type == NPY_LONG && sizeof(int) == sizeof(long))) { format[ 10 ] = 'i'; pbadval = &badval_i; } else { @@ -1363,7 +1347,7 @@ static PyObject *Mapping_rebinseq( Mapping *self, PyObject *args ) { } /* Report an error if the weights array is not double. */ - if( ((PyArrayObject*) weights_object)->descr->type_num != PyArray_DOUBLE ) { + if( ((PyArrayObject*) weights_object)->descr->type_num != NPY_DOUBLE ) { PyErr_Format( PyExc_ValueError, "The 'weights' array supplied to " NAME " is of type %s not not of type float64.", numpydtype2str(((PyArrayObject*) weights_object)->descr->type_num)); @@ -1421,10 +1405,10 @@ static PyObject *Mapping_rebinseq( Mapping *self, PyObject *args ) { for( i = 0; i < ndim; i++ ) { wdims[ i + 1 ] = dims[ i ]; } - weights = GetArray( weights_object, PyArray_DOUBLE, 1, ndim + 1, + weights = GetArray( weights_object, NPY_DOUBLE, 1, ndim + 1, wdims, "weights", NAME ); } else { - weights = GetArray( weights_object, PyArray_DOUBLE, 1, ndim, + weights = GetArray( weights_object, NPY_DOUBLE, 1, ndim, dims, "weights", NAME ); } @@ -1432,7 +1416,7 @@ static PyObject *Mapping_rebinseq( Mapping *self, PyObject *args ) { in && out && weights ) { nused = lnused; - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { astRebinSeqD( THIS, wlim, ncoord_in, (const int *)lbnd_in->data, (const int *)ubnd_in->data, (const double *)in->data, (in_var ? (const double *)in_var->data : NULL), @@ -1444,7 +1428,7 @@ static PyObject *Mapping_rebinseq( Mapping *self, PyObject *args ) { (out_var ? (double *)out_var->data : NULL ), (double *)weights->data, &nused ); - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { astRebinSeqF( THIS, wlim, ncoord_in, (const int *)lbnd_in->data, (const int *)ubnd_in->data, (const float *)in->data, (in_var ? (const float *)in_var->data : NULL), @@ -1572,31 +1556,31 @@ static PyObject *Mapping_resample( Mapping *self, PyObject *args ) { } else { type = ((PyArrayObject*) in_object)->descr->type_num; - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { format[ 9 ] = 'd'; pbadval = &badval_d; - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { format[ 9 ] = 'f'; pbadval = &badval_f; - } else if( type == PyArray_INT ) { + } else if( type == NPY_INT ) { format[ 9 ] = 'i'; pbadval = &badval_i; - } else if( type == PyArray_LONG ) { + } else if( type == NPY_LONG ) { format[ 9 ] = 'l'; pbadval = &badval_l; - } else if( type == PyArray_SHORT ) { + } else if( type == NPY_SHORT ) { format[ 9 ] = 'h'; pbadval = &badval_h; - } else if( type == PyArray_BYTE ) { + } else if( type == NPY_BYTE ) { format[ 9 ] = 'b'; pbadval = &badval_b; - } else if( type == PyArray_UINT ) { + } else if( type == NPY_UINT ) { format[ 9 ] = 'I'; pbadval = &badval_I; - } else if( type == PyArray_USHORT ) { + } else if( type == NPY_USHORT ) { format[ 9 ] = 'H'; pbadval = &badval_H; - } else if( type == PyArray_UBYTE ) { + } else if( type == NPY_UBYTE ) { format[ 9 ] = 'B'; pbadval = &badval_B; } else { @@ -1664,7 +1648,7 @@ static PyObject *Mapping_resample( Mapping *self, PyObject *args ) { pdims_out, type ); if( out && ( ( in_var && out_var ) || !in_var ) ) { - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { noutpix = astResampleD( THIS, ncoord_in, (const int *)lbnd_in->data, (const int *)ubnd_in->data, (const double *)in->data, (in_var ? (const double *)in_var->data : NULL), @@ -1674,7 +1658,7 @@ static PyObject *Mapping_resample( Mapping *self, PyObject *args ) { (const int *)lbnd->data, (const int *)ubnd->data, (double *)out->data, (out_var ? (double *)out_var->data : NULL ) ); - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { noutpix = astResampleF( THIS, ncoord_in, (const int *)lbnd_in->data, (const int *)ubnd_in->data, (const float *)in->data, (in_var ? (const float *)in_var->data : NULL), @@ -1684,7 +1668,7 @@ static PyObject *Mapping_resample( Mapping *self, PyObject *args ) { (const int *)lbnd->data, (const int *)ubnd->data, (float *)out->data, (out_var ? (float *)out_var->data : NULL ) ); - } else if( type == PyArray_LONG ) { + } else if( type == NPY_LONG ) { noutpix = astResampleL( THIS, ncoord_in, (const int *)lbnd_in->data, (const int *)ubnd_in->data, (const long *)in->data, (in_var ? (const long *)in_var->data : NULL), @@ -1694,7 +1678,7 @@ static PyObject *Mapping_resample( Mapping *self, PyObject *args ) { (const int *)lbnd->data, (const int *)ubnd->data, (long *)out->data, (out_var ? (long *)out_var->data : NULL ) ); - } else if( type == PyArray_INT ) { + } else if( type == NPY_INT ) { noutpix = astResampleI( THIS, ncoord_in, (const int *)lbnd_in->data, (const int *)ubnd_in->data, (const int *)in->data, (in_var ? (const int *)in_var->data : NULL), @@ -1704,7 +1688,7 @@ static PyObject *Mapping_resample( Mapping *self, PyObject *args ) { (const int *)lbnd->data, (const int *)ubnd->data, (int *)out->data, (out_var ? (int *)out_var->data : NULL ) ); - } else if( type == PyArray_SHORT ) { + } else if( type == NPY_SHORT ) { noutpix = astResampleS( THIS, ncoord_in, (const int *)lbnd_in->data, (const int *)ubnd_in->data, (const short int *)in->data, (in_var ? (const short int *)in_var->data : NULL), @@ -1714,7 +1698,7 @@ static PyObject *Mapping_resample( Mapping *self, PyObject *args ) { (const int *)lbnd->data, (const int *)ubnd->data, (short int *)out->data, (out_var ? (short int *)out_var->data : NULL ) ); - } else if( type == PyArray_BYTE ) { + } else if( type == NPY_BYTE ) { noutpix = astResampleB( THIS, ncoord_in, (const int *)lbnd_in->data, (const int *)ubnd_in->data, (const signed char *)in->data, (in_var ? (const signed char *)in_var->data : NULL), @@ -1724,7 +1708,7 @@ static PyObject *Mapping_resample( Mapping *self, PyObject *args ) { (const int *)lbnd->data, (const int *)ubnd->data, (signed char *)out->data, (out_var ? (signed char *)out_var->data : NULL ) ); - } else if( type == PyArray_UINT ) { + } else if( type == NPY_UINT ) { noutpix = astResampleUI( THIS, ncoord_in, (const int *)lbnd_in->data, (const int *)ubnd_in->data, (const unsigned int *)in->data, (in_var ? (const unsigned int *)in_var->data : NULL), @@ -1734,7 +1718,7 @@ static PyObject *Mapping_resample( Mapping *self, PyObject *args ) { (const int *)lbnd->data, (const int *)ubnd->data, (unsigned int *)out->data, (out_var ? (unsigned int *)out_var->data : NULL ) ); - } else if( type == PyArray_USHORT ) { + } else if( type == NPY_USHORT ) { noutpix = astResampleUS( THIS, ncoord_in, (const int *)lbnd_in->data, (const int *)ubnd_in->data, (const unsigned short int *)in->data, (in_var ? (const unsigned short int *)in_var->data : NULL), @@ -1744,7 +1728,7 @@ static PyObject *Mapping_resample( Mapping *self, PyObject *args ) { (const int *)lbnd->data, (const int *)ubnd->data, (unsigned short int *)out->data, (out_var ? (unsigned short int *)out_var->data : NULL ) ); - } else if( type == PyArray_UBYTE ) { + } else if( type == NPY_UBYTE ) { noutpix = astResampleUB( THIS, ncoord_in, (const int *)lbnd_in->data, (const int *)ubnd_in->data, (const unsigned char *)in->data, (in_var ? (const unsigned char *)in_var->data : NULL), @@ -1888,7 +1872,7 @@ static PyObject *Mapping_trangrid( Mapping *self, PyObject *args ) { dims[ 0 ] = ncoord_out; dims[ 1 ] = outdim; - pout = (PyArrayObject *) PyArray_SimpleNew( 2, dims, PyArray_DOUBLE ); + pout = (PyArrayObject *) PyArray_SimpleNew( 2, dims, NPY_DOUBLE ); if( pout ) { astTranGrid( THIS, ncoord_in, (const int *)lbnd->data, @@ -1967,12 +1951,12 @@ static PyObject *Mapping_tran( Mapping *self, PyObject *args ) { dims[ 0 ] = ncoord_in; dims[ 1 ] = 0; - in = GetArray( in_object, PyArray_DOUBLE, 0, 2, dims, "in", NAME ); + in = GetArray( in_object, NPY_DOUBLE, 0, 2, dims, "in", NAME ); if( in ) { dims[ 0 ] = ncoord_out; if( out_object ) { - out = GetArray( out_object, PyArray_DOUBLE, 0, 2, dims, "out", NAME ); + out = GetArray( out_object, NPY_DOUBLE, 0, 2, dims, "out", NAME ); } else { if( in->nd == 1 ){ ndim = 1; @@ -1983,7 +1967,7 @@ static PyObject *Mapping_tran( Mapping *self, PyObject *args ) { pdims[ 1 ] = dims[ 1 ]; } out = (PyArrayObject *) PyArray_SimpleNew( ndim, pdims, - PyArray_DOUBLE ); + NPY_DOUBLE ); } } @@ -2814,7 +2798,7 @@ static PyObject *TimeMap_timeadd( TimeMap *self, PyObject *args ) { have in "args" to make sure it is correct. Putting the code here and in AST seems silly though. */ astargs = (PyArrayObject *) PyArray_ContiguousFromAny( astargs_object, - PyArray_DOUBLE, 0, 100); + NPY_DOUBLE, 0, 100); if (astargs) { astTimeAdd( THIS, cvt, astargs->dimensions[0], (const double *)astargs->data ); if( astOK ) { @@ -3145,12 +3129,12 @@ static int PermMap_init( PermMap *self, PyObject *args, PyObject *kwds ){ if( PyArg_ParseTuple(args, "OO|Os:" CLASS, &inperm_object, &outperm_object, &constant_object, &options ) ) { inperm = (PyArrayObject *) PyArray_ContiguousFromAny( inperm_object, - PyArray_INT, 0, 100); + NPY_INT, 0, 100); outperm = (PyArrayObject *) PyArray_ContiguousFromAny( outperm_object, - PyArray_INT, 0, 100); + NPY_INT, 0, 100); if (constant_object) { constant = (PyArrayObject *) PyArray_ContiguousFromAny( constant_object, - PyArray_DOUBLE, 0, 100); + NPY_DOUBLE, 0, 100); } if (inperm && outperm) { AstPermMap * this = NULL; @@ -3249,7 +3233,7 @@ static int ShiftMap_init( ShiftMap *self, PyObject *args, PyObject *kwds ){ if( PyArg_ParseTuple(args, "O|s:" CLASS, &shift_object, &options ) ) { shift = (PyArrayObject *) PyArray_ContiguousFromAny( shift_object, - PyArray_DOUBLE, 0, 100); + NPY_DOUBLE, 0, 100); if (shift) { AstShiftMap * this = NULL; this = astShiftMap( PyArray_Size( (PyObject*)shift), @@ -3337,7 +3321,7 @@ static int UnitNormMap_init( UnitNormMap *self, PyObject *args, PyObject *kwds ) // We get nin and nout from the arrays themselves if( PyArg_ParseTuple(args, "O|s:" CLASS, ¢re_object, &options ) ) { centre = (PyArrayObject *) PyArray_ContiguousFromAny( centre_object, - PyArray_DOUBLE, 0, 100); + NPY_DOUBLE, 0, 100); if( centre ) { AstUnitNormMap *this = NULL; this = astUnitNormMap( PyArray_Size( (PyObject*)centre ), @@ -3427,7 +3411,7 @@ static int LutMap_init( LutMap *self, PyObject *args, PyObject *kwds ){ if( PyArg_ParseTuple(args, "O|dds:" CLASS, &lut_object, &start, &inc, &options ) ) { lut = (PyArrayObject *) PyArray_ContiguousFromAny( lut_object, - PyArray_DOUBLE, 0, 100); + NPY_DOUBLE, 0, 100); if (lut) { AstLutMap * this = NULL; this = astLutMap( PyArray_Size( (PyObject*)lut), @@ -3522,13 +3506,13 @@ static int WinMap_init( WinMap *self, PyObject *args, PyObject *kwds ){ if( PyArg_ParseTuple(args, "OOOO|s:" CLASS, &ina_object, &inb_object, &outa_object, &outb_object, &options ) ) { ina = (PyArrayObject *) PyArray_ContiguousFromAny( ina_object, - PyArray_DOUBLE, 0, 100); + NPY_DOUBLE, 0, 100); inb = (PyArrayObject *) PyArray_ContiguousFromAny( inb_object, - PyArray_DOUBLE, 0, 100); + NPY_DOUBLE, 0, 100); outa = (PyArrayObject *) PyArray_ContiguousFromAny( outa_object, - PyArray_DOUBLE, 0, 100); + NPY_DOUBLE, 0, 100); outb = (PyArrayObject *) PyArray_ContiguousFromAny( outb_object, - PyArray_DOUBLE, 0, 100); + NPY_DOUBLE, 0, 100); if (ina && inb && outa && outb ) { AstWinMap * this = NULL; // Sanity check size @@ -4007,7 +3991,7 @@ static PyObject *Frame_intersect( Frame *self, PyObject *args ) { b1 = GetArray1D( b1_object, &naxes, "b1", NAME ); b2 = GetArray1D( b2_object, &naxes, "b2", NAME ); dims[0] = naxes; - out = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + out = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if (a1 && a2 && b1 && b2 && out ) { astIntersect( THIS, (const double *)a1->data, (const double *)a2->data, @@ -4042,7 +4026,7 @@ static PyObject *Frame_matchaxes( Frame *self, PyObject *args ) { if( PyArg_ParseTuple( args, "O!:" NAME, &FrameType, (PyObject **) &other ) && astOK ) { dims[0] = astGetI( THAT, "Naxes" ); - axes = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_INT ); + axes = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_INT ); if (axes) { astMatchAxes( THIS, THAT, (int *)axes->data ); if( astOK ) result = Py_BuildValue("O", PyArray_Return(axes)); @@ -4095,7 +4079,7 @@ static PyObject *Frame_norm( Frame *self, PyObject *args ) { /* Get a PyArrayObject from the PyObject, allowing any number of dimensions. */ value = (PyArrayObject *) PyArray_ContiguousFromAny( value_object, - PyArray_DOUBLE, 0, 100 ); + NPY_DOUBLE, 0, 100 ); if( value ) { /* In all cases the length of the first dimensions should be "naxes". */ @@ -4112,7 +4096,7 @@ static PyObject *Frame_norm( Frame *self, PyObject *args ) { output array and then call astNorm to normalise it. */ } else if( value->nd == 1 ) { dims[0] = naxes; - axes = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + axes = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if ( value && axes ) { memcpy( axes->data, value->data, sizeof(double)*naxes); astNorm( THIS, (double *)axes->data ); @@ -4128,7 +4112,7 @@ static PyObject *Frame_norm( Frame *self, PyObject *args ) { dims[0] = naxes; dims[1] = npos; - axes = (PyArrayObject *) PyArray_SimpleNew( 2, dims, PyArray_DOUBLE ); + axes = (PyArrayObject *) PyArray_SimpleNew( 2, dims, NPY_DOUBLE ); if ( value && axes ) { @@ -4228,12 +4212,12 @@ static PyObject *Frame_normpoints( Frame *self, PyObject *args ) { dims[ 0 ] = naxes; dims[ 1 ] = 0; - in = GetArray( in_object, PyArray_DOUBLE, 0, 2, dims, "in", NAME ); + in = GetArray( in_object, NPY_DOUBLE, 0, 2, dims, "in", NAME ); if( in ) { dims[ 0 ] = naxes; if( out_object ) { - out = GetArray( out_object, PyArray_DOUBLE, 0, 2, dims, "out", NAME ); + out = GetArray( out_object, NPY_DOUBLE, 0, 2, dims, "out", NAME ); } else { if( in->nd == 1 ){ ndim = 1; @@ -4244,7 +4228,7 @@ static PyObject *Frame_normpoints( Frame *self, PyObject *args ) { pdims[ 1 ] = dims[ 1 ]; } out = (PyArrayObject *) PyArray_SimpleNew( ndim, pdims, - PyArray_DOUBLE ); + NPY_DOUBLE ); } } @@ -4286,7 +4270,7 @@ static PyObject *Frame_offset( Frame *self, PyObject *args ) { point1 = GetArray1D( point1_object, &naxes, "point1", NAME ); point2 = GetArray1D( point2_object, &naxes, "point2", NAME ); dims[0] = naxes; - point3 = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + point3 = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if (point1 && point2 && point3 ) { astOffset( THIS, (const double *)point1->data, (const double *)point2->data, offset, @@ -4324,7 +4308,7 @@ static PyObject *Frame_offset2( Frame *self, PyObject *args ) { &angle, &offset ) && astOK ) { point1 = GetArray1D( point1_object, &naxes, "point1", NAME ); dims[0] = naxes; - point2 = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + point2 = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if (point1 && point2 ) { double direction = astOffset2( THIS, (const double *)point1->data, angle, offset, @@ -4384,7 +4368,7 @@ static PyObject *Frame_pickaxes( Frame *self, PyObject *args ) { // We get naxes from the axes argument if ( PyArg_ParseTuple( args, "O:" NAME, &axes_object ) && astOK ) { axes = (PyArrayObject *) PyArray_ContiguousFromAny( axes_object, - PyArray_INT, 0, 100); + NPY_INT, 0, 100); if (axes) { AstMapping *map = NULL; AstFrame * frame = NULL; @@ -4441,7 +4425,7 @@ static PyObject *Frame_resolve( Frame *self, PyObject *args ) { point2 = GetArray1D( point2_object, &naxes, "point2", NAME ); point3 = GetArray1D( point3_object, &naxes, "point3", NAME ); dims[0] = naxes; - point4 = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + point4 = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if (point1 && point2 && point3 && point4) { double d1; double d2; @@ -4565,7 +4549,7 @@ static int MatrixMap_init( MatrixMap *self, PyObject *args, PyObject *kwds ){ if( PyArg_ParseTuple(args, "O|s:" CLASS, &matrix_object, &options ) ) { PyArrayObject *matrix = (PyArrayObject *) PyArray_ContiguousFromAny( matrix_object, - PyArray_DOUBLE, 0, 100); + NPY_DOUBLE, 0, 100); if( matrix ) { int ndim = matrix->nd; @@ -4695,7 +4679,7 @@ static int PolyMap_init( PolyMap *self, PyObject *args, PyObject *kwds ){ if( fcoeff_object && fcoeff_object != Py_None ) { fcoeff = (PyArrayObject *) PyArray_ContiguousFromAny( fcoeff_object, - PyArray_DOUBLE, + NPY_DOUBLE, 0, 100); if( fcoeff ) { if( fcoeff->nd != 2 ) { @@ -4719,7 +4703,7 @@ static int PolyMap_init( PolyMap *self, PyObject *args, PyObject *kwds ){ if( icoeff_object && icoeff_object != Py_None ) { icoeff = (PyArrayObject *) PyArray_ContiguousFromAny( icoeff_object, - PyArray_DOUBLE, + NPY_DOUBLE, 0, 100); if( icoeff ) { if( icoeff->nd != 2 ) { @@ -4913,7 +4897,7 @@ static int ChebyMap_init( ChebyMap *self, PyObject *args, PyObject *kwds ){ if( fcoeff_object && fcoeff_object != Py_None ) { fcoeff = (PyArrayObject *) PyArray_ContiguousFromAny( fcoeff_object, - PyArray_DOUBLE, + NPY_DOUBLE, 0, 100); if( fcoeff ) { if( fcoeff->nd != 2 ) { @@ -4939,7 +4923,7 @@ static int ChebyMap_init( ChebyMap *self, PyObject *args, PyObject *kwds ){ if( icoeff_object && icoeff_object != Py_None ) { icoeff = (PyArrayObject *) PyArray_ContiguousFromAny( icoeff_object, - PyArray_DOUBLE, + NPY_DOUBLE, 0, 100); if( icoeff ) { if( icoeff->nd != 2 ) { @@ -6391,8 +6375,8 @@ static PyObject *Region_getregionbounds( Region *self ) { naxes = astGetI( THIS, "Naxes" ); dims[0] = naxes; - lbnd = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); - ubnd = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + lbnd = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); + ubnd = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if( lbnd && ubnd ) { astGetRegionBounds( THIS, (double *)lbnd->data, (double*)ubnd->data ); if( astOK ) result = Py_BuildValue("OO", PyArray_Return(lbnd), @@ -6421,7 +6405,7 @@ static PyObject *Region_getregiondisc( Region *self ) { naxes = astGetI( THIS, "Naxes" ); dims[0] = naxes; - centre = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + centre = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if( centre ) { astGetRegionDisc( THIS, (double *)centre->data, &radius ); if( astOK ) result = Py_BuildValue( "Od", PyArray_Return(centre), @@ -6551,7 +6535,7 @@ static PyObject *Region_getregionpoints( Region *self, PyObject *args ) { /* Create the returned array. */ dims[0] = naxes; dims[1] = npoint; - points = (PyArrayObject *) PyArray_SimpleNew( 2, dims, PyArray_DOUBLE ); + points = (PyArrayObject *) PyArray_SimpleNew( 2, dims, NPY_DOUBLE ); /* If successful, put the axis values at the required positions into the array. */ @@ -6600,7 +6584,7 @@ static PyObject *Region_getregionmesh( Region *self, PyObject *args ) { /* Create the returned array. */ dims[0] = naxes; dims[1] = npoint; - points = (PyArrayObject *) PyArray_SimpleNew( 2, dims, PyArray_DOUBLE ); + points = (PyArrayObject *) PyArray_SimpleNew( 2, dims, NPY_DOUBLE ); } /* If successful, put the axis values at the required positions into the @@ -6669,31 +6653,31 @@ static PyObject *Region_mask( Region *self, PyObject *args ) { "an array object" ); } else { type = ((PyArrayObject*) in_object)->descr->type_num; - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { format[ 6 ] = 'd'; pval = &val_d; - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { format[ 6 ] = 'f'; pval = &val_f; - } else if( type == PyArray_INT ) { + } else if( type == NPY_INT ) { format[ 6 ] = 'i'; pval = &val_i; - } else if( type == PyArray_LONG ) { + } else if( type == NPY_LONG ) { format[ 6 ] = 'l'; pval = &val_l; - } else if( type == PyArray_SHORT ) { + } else if( type == NPY_SHORT ) { format[ 6 ] = 'h'; pval = &val_h; - } else if( type == PyArray_BYTE ) { + } else if( type == NPY_BYTE ) { format[ 6 ] = 'b'; pval = &val_b; - } else if( type == PyArray_UINT ) { + } else if( type == NPY_UINT ) { format[ 6 ] = 'I'; pval = &val_I; - } else if( type == PyArray_USHORT ) { + } else if( type == NPY_USHORT ) { format[ 6 ] = 'H'; pval = &val_H; - } else if( type == PyArray_UBYTE ) { + } else if( type == NPY_UBYTE ) { format[ 6 ] = 'B'; pval = &val_B; } else { @@ -6739,39 +6723,39 @@ static PyObject *Region_mask( Region *self, PyObject *args ) { in = GetArray( in_object, type, 1, ndim, dims, "in", NAME ); if( lbnd && ubnd && in ){ - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { nmasked = astMaskD( THIS, THAT, inside, ndim, lbnd_vals, ubnd_vals, (double *)in->data, val_d ); - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { nmasked = astMaskF( THIS, THAT, inside, ndim, lbnd_vals, ubnd_vals, (float *)in->data, val_f ); - } else if( type == PyArray_LONG ) { + } else if( type == NPY_LONG ) { nmasked = astMaskL( THIS, THAT, inside, ndim, lbnd_vals, ubnd_vals, (long *)in->data, val_l ); - } else if( type == PyArray_INT ) { + } else if( type == NPY_INT ) { nmasked = astMaskI( THIS, THAT, inside, ndim, lbnd_vals, ubnd_vals, (int *)in->data, val_i ); - } else if( type == PyArray_SHORT ) { + } else if( type == NPY_SHORT ) { nmasked = astMaskS( THIS, THAT, inside, ndim, lbnd_vals, ubnd_vals, (short int *)in->data, val_h ); - } else if( type == PyArray_BYTE ) { + } else if( type == NPY_BYTE ) { nmasked = astMaskB( THIS, THAT, inside, ndim, lbnd_vals, ubnd_vals, (signed char *)in->data, val_b ); - } else if( type == PyArray_UINT ) { + } else if( type == NPY_UINT ) { nmasked = astMaskUI( THIS, THAT, inside, ndim, lbnd_vals, ubnd_vals, (unsigned int *)in->data, val_I ); - } else if( type == PyArray_USHORT ) { + } else if( type == NPY_USHORT ) { nmasked = astMaskUS( THIS, THAT, inside, ndim, lbnd_vals, ubnd_vals, (unsigned short int *)in->data, val_H ); - } else if( type == PyArray_UBYTE ) { + } else if( type == NPY_UBYTE ) { nmasked = astMaskUB( THIS, THAT, inside, ndim, lbnd_vals, ubnd_vals, (unsigned char *)in->data, val_B ); @@ -7038,8 +7022,8 @@ static PyObject *Circle_circlepars( Circle *self, PyObject *args ) { if( PyErr_Occurred() ) return NULL; dims[0] = astGetI( THIS, "Naxes" ); - centre = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); - p1 = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + centre = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); + p1 = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if( centre && p1 ) { astCirclePars( THIS, (double *)centre->data, &radius, (double *)p1->data ); if( astOK ) result = Py_BuildValue( "OdO", PyArray_Return(centre), @@ -7228,11 +7212,11 @@ static PyObject *Moc_addmocdata( Moc *self, PyObject *args ) { "an array object" ); } else { type = ((PyArrayObject*) data_object)->descr->type_num; - if( type == PyArray_INT ) { + if( type == NPY_INT ) { nbyte = sizeof(int); - } else if( type == PyArray_LONG ) { + } else if( type == NPY_LONG ) { nbyte = sizeof(long int); - } else if( type == PyArray_LONGLONG ) { + } else if( type == NPY_LONGLONG ) { nbyte = sizeof(long long int); } else { PyErr_SetString( PyExc_ValueError, "The 'data' array supplied " @@ -7354,39 +7338,39 @@ static PyObject *Moc_addpixelmask( Moc *self, PyObject *args ) { "an array object" ); } else { type = ((PyArrayObject*) array_object)->descr->type_num; - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { format[ 2 ] = 'd'; pvalue = &value_d; pbadval = &badval_d; - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { format[ 2 ] = 'f'; pvalue = &value_f; pbadval = &badval_f; - } else if( type == PyArray_INT ) { + } else if( type == NPY_INT ) { format[ 2 ] = 'i'; pvalue = &value_i; pbadval = &badval_i; - } else if( type == PyArray_LONG ) { + } else if( type == NPY_LONG ) { format[ 2 ] = 'l'; pvalue = &value_l; pbadval = &badval_l; - } else if( type == PyArray_SHORT ) { + } else if( type == NPY_SHORT ) { format[ 2 ] = 'h'; pvalue = &value_h; pbadval = &badval_h; - } else if( type == PyArray_BYTE ) { + } else if( type == NPY_BYTE ) { format[ 2 ] = 'b'; pvalue = &value_b; pbadval = &badval_b; - } else if( type == PyArray_UINT ) { + } else if( type == NPY_UINT ) { format[ 2 ] = 'I'; pvalue = &value_I; pbadval = &badval_I; - } else if( type == PyArray_USHORT ) { + } else if( type == NPY_USHORT ) { format[ 2 ] = 'H'; pvalue = &value_H; pbadval = &badval_H; - } else if( type == PyArray_UBYTE ) { + } else if( type == NPY_UBYTE ) { format[ 2 ] = 'B'; pvalue = &value_B; pbadval = &badval_B; @@ -7425,39 +7409,39 @@ static PyObject *Moc_addpixelmask( Moc *self, PyObject *args ) { array = GetArray( array_object, type, 1, 2, dims, "array", NAME ); if( array ) { - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { astAddPixelMaskD( THIS, cmode, THAT, value_d, oper, flags, badval_d, (const double *)array->data, dims ); - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { astAddPixelMaskF( THIS, cmode, THAT, value_f, oper, flags, badval_f, (const float *)array->data, dims ); - } else if( type == PyArray_LONG ) { + } else if( type == NPY_LONG ) { astAddPixelMaskL( THIS, cmode, THAT, value_l, oper, flags, badval_l, (const long int *)array->data, dims ); - } else if( type == PyArray_INT ) { + } else if( type == NPY_INT ) { astAddPixelMaskI( THIS, cmode, THAT, value_i, oper, flags, badval_i, (const int *)array->data, dims ); - } else if( type == PyArray_SHORT ) { + } else if( type == NPY_SHORT ) { astAddPixelMaskS( THIS, cmode, THAT, value_h, oper, flags, badval_h, (const short int *)array->data, dims ); - } else if( type == PyArray_BYTE ) { + } else if( type == NPY_BYTE ) { astAddPixelMaskB( THIS, cmode, THAT, value_b, oper, flags, badval_b, (const signed char *)array->data, dims ); - } else if( type == PyArray_UINT ) { + } else if( type == NPY_UINT ) { astAddPixelMaskUI( THIS, cmode, THAT, value_I, oper, flags, badval_I, (const unsigned int *)array->data, dims ); - } else if( type == PyArray_USHORT ) { + } else if( type == NPY_USHORT ) { astAddPixelMaskUS( THIS, cmode, THAT, value_H, oper, flags, badval_H, (const unsigned short int *)array->data, dims ); - } else if( type == PyArray_UBYTE ) { + } else if( type == NPY_UBYTE ) { astAddPixelMaskUB( THIS, cmode, THAT, value_B, oper, flags, badval_B, (const unsigned char *)array->data, dims ); @@ -7548,7 +7532,7 @@ static PyObject *Moc_getmocdata( Moc *self, PyObject *args ) { /* Create a suitable numpy array in which to store the data values. */ dims[ 0 ] = len; data = (PyArrayObject *) PyArray_SimpleNew( 1, dims, - ( nbyte == 4 ) ? PyArray_INT : PyArray_LONGLONG ); + ( nbyte == 4 ) ? NPY_INT : NPY_LONGLONG ); if( data ) { astGetMocData( THIS, dims[ 0 ]*nbyte, data->data ); if( astOK ) result = Py_BuildValue( "O", data ); @@ -7723,7 +7707,7 @@ static int Polygon_init( Polygon *self, PyObject *args, PyObject *kwds ){ &options ) ) { dims[ 0 ] = 2; dims[ 1 ] = 0; - points = GetArray( points_object, PyArray_DOUBLE, 0, 2, dims, "points", + points = GetArray( points_object, NPY_DOUBLE, 0, 2, dims, "points", NAME ); if( points ) { AstRegion *unc = NULL; @@ -7855,7 +7839,7 @@ static int PointList_init( PointList *self, PyObject *args, PyObject *kwds ){ int ncoord = astGetI( THAT, "Naxes" ); dims[ 0 ] = ncoord; dims[ 1 ] = 0; - points = GetArray( points_object, PyArray_DOUBLE, 0, 2, dims, "points", + points = GetArray( points_object, NPY_DOUBLE, 0, 2, dims, "points", NAME ); if( points ) { AstRegion *unc = NULL; @@ -8000,9 +7984,9 @@ static PyObject *Ellipse_ellipsepars( Ellipse *self, PyObject *args ) { if( PyErr_Occurred() ) return NULL; dims[0] = astGetI( THIS, "Naxes" ); - centre = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); - p1 = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); - p2 = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + centre = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); + p1 = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); + p2 = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if( centre && p1 && p2 ) { astEllipsePars( THIS, (double *)centre->data, &a, &b, &angle, (double *)p1->data, (double *)p2->data ); @@ -10496,19 +10480,19 @@ static int KeyMap_setitem( PyObject *self, PyObject *index, PyObject *value ){ for( i = 0; i < array->nd; i++ ) { nval *= (array->dimensions)[ i ]; } - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { astMapPut1D( THIS, key, nval, (const double *) array->data, NULL ); - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { astMapPut1F( THIS, key, nval, (const float *) array->data, NULL ); - } else if( type == PyArray_INT ) { + } else if( type == NPY_INT ) { astMapPut1I( THIS, key, nval, (const int *) array->data, NULL ); - } else if( type == PyArray_SHORT ) { + } else if( type == NPY_SHORT ) { astMapPut1S( THIS, key, nval, (const short int *) array->data, NULL ); - } else if( type == PyArray_UBYTE ) { + } else if( type == NPY_UBYTE ) { astMapPut1B( THIS, key, nval, (const unsigned char *) array->data, NULL ); } else { @@ -10870,13 +10854,13 @@ static PyObject *Plot_boundingbox( Plot *self, PyObject *args ) { if( astOK ) { npy_intp dims[1]; dims[0] = 2; - PyArrayObject *lbnd = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + PyArrayObject *lbnd = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if( lbnd ) { double *v = (double *)lbnd->data; v[ 0 ] = flbnd[ 0 ]; v[ 1 ] = flbnd[ 1 ]; } - PyArrayObject *ubnd = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + PyArrayObject *ubnd = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if( ubnd ) { double *v = (double *)ubnd->data; v[ 0 ] = fubnd[ 0 ]; @@ -11060,7 +11044,7 @@ static PyObject *Plot_mark( Plot *self, PyObject *args ) { int dims[ 2 ]; dims[ 0 ] = astGetI( THIS, "Naxes" ); dims[ 1 ] = 0; - PyArrayObject *in = GetArray( in_object, PyArray_DOUBLE, 1, 2, dims, + PyArrayObject *in = GetArray( in_object, NPY_DOUBLE, 1, 2, dims, "in", NAME ); if( in ) { astMark( THIS, dims[ 1 ], dims[ 0 ], dims[ 1 ], @@ -11092,7 +11076,7 @@ static PyObject *Plot_polycurve( Plot *self, PyObject *args ) { int dims[ 2 ]; dims[ 0 ] = astGetI( THIS, "Naxes" ); dims[ 1 ] = 0; - PyArrayObject *in = GetArray( in_object, PyArray_DOUBLE, 0, 2, dims, + PyArrayObject *in = GetArray( in_object, NPY_DOUBLE, 0, 2, dims, "in", NAME ); if( in ) { astPolyCurve( THIS, dims[ 1 ], dims[ 0 ], dims[ 1 ], @@ -11427,8 +11411,8 @@ static int Line_wrapper( AstObject *grfcon, int n, const float *x, const float * if( self && self->grf ) { dims[ 0 ] = n; - PyArrayObject *xo = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); - PyArrayObject *yo = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + PyArrayObject *xo = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); + PyArrayObject *yo = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if( xo && yo ) { int i; @@ -11460,8 +11444,8 @@ static int Mark_wrapper( AstObject *grfcon, int n, const float *x, const float * if( self && self->grf ) { dims[ 0 ] = n; - PyArrayObject *xo = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); - PyArrayObject *yo = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_DOUBLE ); + PyArrayObject *xo = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); + PyArrayObject *yo = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_DOUBLE ); if( xo && yo ) { int i; @@ -11827,7 +11811,7 @@ static PyObject *Table_columnshape( Table *self, PyObject *args ) { sprintf( buf, "ColumnNdim(%s)", column ); ndim = astGetI( THIS, buf ); dims[ 0 ] = ndim; - PyArrayObject *dims_array = (PyArrayObject *) PyArray_SimpleNew( 1, dims, PyArray_INT ); + PyArrayObject *dims_array = (PyArrayObject *) PyArray_SimpleNew( 1, dims, NPY_INT ); if( dims_array ) { astColumnShape( THIS, column, ndim, &ndim, (int *) dims_array->data ); if( astOK ) { @@ -12632,34 +12616,34 @@ static PyObject *PyAst_convex( PyObject *self, PyObject *args ) { "an array object" ); } else { type = ((PyArrayObject*) array_object)->descr->type_num; - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { format[ 0 ] = 'd'; pvalue = &value_d; - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { format[ 0 ] = 'f'; pvalue = &value_f; - } else if( type == PyArray_INT ) { + } else if( type == NPY_INT ) { format[ 0 ] = 'i'; pvalue = &value_i; - } else if( type == PyArray_LONG ) { + } else if( type == NPY_LONG ) { format[ 0 ] = 'l'; pvalue = &value_l; - } else if( type == PyArray_UINT ) { + } else if( type == NPY_UINT ) { format[ 0 ] = 'I'; pvalue = &value_I; - } else if( type == PyArray_ULONG ) { + } else if( type == NPY_ULONG ) { format[ 0 ] = 'L'; pvalue = &value_L; - } else if( type == PyArray_SHORT ) { + } else if( type == NPY_SHORT ) { format[ 0 ] = 'h'; pvalue = &value_h; - } else if( type == PyArray_USHORT ) { + } else if( type == NPY_USHORT ) { format[ 0 ] = 'H'; pvalue = &value_H; - } else if( type == PyArray_BYTE ) { + } else if( type == NPY_BYTE ) { format[ 0 ] = 'b'; pvalue = &value_b; - } else if( type == PyArray_UBYTE ) { + } else if( type == NPY_UBYTE ) { format[ 0 ] = 'B'; pvalue = &value_B; } else { @@ -12695,43 +12679,43 @@ static PyObject *PyAst_convex( PyObject *self, PyObject *args ) { if( array && lbnd && ubnd ) { AstPolygon *new = NULL; - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { new = astConvexD( value_d, oper, (const double *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, starpix ); - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { new = astConvexF( value_f, oper, (const float *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, starpix ); - } else if( type == PyArray_LONG) { + } else if( type == NPY_LONG) { new = astConvexL( value_l, oper, (const long int *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, starpix ); - } else if( type == PyArray_INT) { + } else if( type == NPY_INT) { new = astConvexI( value_i, oper, (const int *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, starpix ); - } else if( type == PyArray_ULONG) { + } else if( type == NPY_ULONG) { new = astConvexUL( value_L, oper, (const unsigned long int *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, starpix ); - } else if( type == PyArray_UINT) { + } else if( type == NPY_UINT) { new = astConvexUI( value_I, oper, (const unsigned int *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, starpix ); - } else if( type == PyArray_SHORT) { + } else if( type == NPY_SHORT) { new = astConvexS( value_h, oper, (const short int *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, starpix ); - } else if( type == PyArray_USHORT) { + } else if( type == NPY_USHORT) { new = astConvexUS( value_H, oper, (const unsigned short int *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, starpix ); - } else if( type == PyArray_BYTE) { + } else if( type == NPY_BYTE) { new = astConvexB( value_b, oper, (const signed char *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, starpix ); - } else if( type == PyArray_UBYTE) { + } else if( type == NPY_UBYTE) { new = astConvexUB( value_B, oper, (const unsigned char *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, starpix ); @@ -12874,34 +12858,34 @@ static PyObject *PyAst_outline( PyObject *self, PyObject *args ) { "an array object" ); } else { type = ((PyArrayObject*) array_object)->descr->type_num; - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { format[ 0 ] = 'd'; pvalue = &value_d; - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { format[ 0 ] = 'f'; pvalue = &value_f; - } else if( type == PyArray_INT ) { + } else if( type == NPY_INT ) { format[ 0 ] = 'i'; pvalue = &value_i; - } else if( type == PyArray_LONG ) { + } else if( type == NPY_LONG ) { format[ 0 ] = 'l'; pvalue = &value_l; - } else if( type == PyArray_UINT ) { + } else if( type == NPY_UINT ) { format[ 0 ] = 'I'; pvalue = &value_I; - } else if( type == PyArray_ULONG ) { + } else if( type == NPY_ULONG ) { format[ 0 ] = 'L'; pvalue = &value_L; - } else if( type == PyArray_SHORT ) { + } else if( type == NPY_SHORT ) { format[ 0 ] = 'h'; pvalue = &value_h; - } else if( type == PyArray_USHORT ) { + } else if( type == NPY_USHORT ) { format[ 0 ] = 'H'; pvalue = &value_H; - } else if( type == PyArray_BYTE ) { + } else if( type == NPY_BYTE ) { format[ 0 ] = 'b'; pvalue = &value_b; - } else if( type == PyArray_UBYTE ) { + } else if( type == NPY_UBYTE ) { format[ 0 ] = 'B'; pvalue = &value_B; } else { @@ -12939,43 +12923,43 @@ static PyObject *PyAst_outline( PyObject *self, PyObject *args ) { if( array && lbnd && ubnd && inside ) { AstPolygon *new = NULL; - if( type == PyArray_DOUBLE ) { + if( type == NPY_DOUBLE ) { new = astOutlineD( value_d, oper, (const double *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, maxerr, maxvert, (const int *)inside->data, starpix ); - } else if( type == PyArray_FLOAT ) { + } else if( type == NPY_FLOAT ) { new = astOutlineF( value_f, oper, (const float *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, maxerr, maxvert, (const int *)inside->data, starpix ); - } else if( type == PyArray_LONG) { + } else if( type == NPY_LONG) { new = astOutlineL( value_l, oper, (const long int *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, maxerr, maxvert, (const int *)inside->data, starpix ); - } else if( type == PyArray_INT) { + } else if( type == NPY_INT) { new = astOutlineI( value_i, oper, (const int *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, maxerr, maxvert, (const int *)inside->data, starpix ); - } else if( type == PyArray_ULONG) { + } else if( type == NPY_ULONG) { new = astOutlineUL( value_L, oper, (const unsigned long int *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, maxerr, maxvert, (const int *)inside->data, starpix ); - } else if( type == PyArray_UINT) { + } else if( type == NPY_UINT) { new = astOutlineUI( value_I, oper, (const unsigned int *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, maxerr, maxvert, (const int *)inside->data, starpix ); - } else if( type == PyArray_SHORT) { + } else if( type == NPY_SHORT) { new = astOutlineS( value_h, oper, (const short int *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, maxerr, maxvert, (const int *)inside->data, starpix ); - } else if( type == PyArray_USHORT) { + } else if( type == NPY_USHORT) { new = astOutlineUS( value_H, oper, (const unsigned short int *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, maxerr, maxvert, (const int *)inside->data, starpix ); - } else if( type == PyArray_BYTE) { + } else if( type == NPY_BYTE) { new = astOutlineB( value_b, oper, (const signed char *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, maxerr, maxvert, (const int *)inside->data, starpix ); - } else if( type == PyArray_UBYTE) { + } else if( type == NPY_UBYTE) { new = astOutlineUB( value_B, oper, (const unsigned char *)array->data, (const int *)lbnd->data, (const int *)ubnd->data, maxerr, maxvert, (const int *)inside->data, starpix ); @@ -14221,7 +14205,7 @@ static PyArrayObject *GetArray1D( PyObject *object, int *dim, const char *arg, * precision values. */ - return GetArray( object, PyArray_DOUBLE, 1, 1, dim, arg, fun ); + return GetArray( object, NPY_DOUBLE, 1, 1, dim, arg, fun ); } static PyArrayObject *GetArray1I( PyObject *object, int *dim, const char *arg, @@ -14236,7 +14220,7 @@ static PyArrayObject *GetArray1I( PyObject *object, int *dim, const char *arg, * values. */ - return GetArray( object, PyArray_INT, 1, 1, dim, arg, fun ); + return GetArray( object, NPY_INT, 1, 1, dim, arg, fun ); } static char *DumpToString( AstObject *this, const char *options ){ From b8787b30084a9537645f51ed6b8cada4677c60f9 Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Sun, 18 Aug 2024 16:19:30 -0700 Subject: [PATCH 4/8] Add build system requirements and black/isort configuration --- pyproject.toml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..ce0af87 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,14 @@ +[build-system] +requires = [ + "numpy", + "setuptools", + "setuptools-scm>=8.0" +] + +[tool.black] +line-length = 110 +target-version = ["py311"] + +[tool.isort] +profile = "black" +line_length = 110 From ce0fdc1f459b915ab903b9f66144f65fe264276c Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Sun, 18 Aug 2024 16:22:09 -0700 Subject: [PATCH 5/8] Fixes from ruff check --- setup.py | 3 +-- starlink/Grf.py | 4 ++-- starlink/ast/test/plothead.py | 7 +++---- starlink/ast/test/test.py | 2 +- starlink/ast/test/test_atl.py | 1 - tools/make_attributes.py | 3 +-- tools/make_exceptions.py | 15 +++++++-------- 7 files changed, 15 insertions(+), 20 deletions(-) diff --git a/setup.py b/setup.py index 00a2771..5a6dee6 100644 --- a/setup.py +++ b/setup.py @@ -1,14 +1,13 @@ -from __future__ import print_function import ctypes import os import re import sys import tarfile -from setuptools import Distribution, Extension, setup from textwrap import dedent import numpy +from setuptools import Distribution, Extension, setup from tools import make_attributes, make_exceptions diff --git a/starlink/Grf.py b/starlink/Grf.py index d4d585b..ea661b7 100644 --- a/starlink/Grf.py +++ b/starlink/Grf.py @@ -21,7 +21,7 @@ """ -class grf_matplotlib(object): +class grf_matplotlib: """ When creating a grf_matplotlib, the supplied "axes" object should be an instance of the matplotlib Axes class (or a subclass). @@ -188,7 +188,7 @@ def find_renderer(self, fig): if not self.renderer: raise AttributeError( "No renderer available using matplotlib " - "backend {0} - use a different backend".format(matplotlib.get_backend()) + f"backend {matplotlib.get_backend()} - use a different backend" ) return self.renderer diff --git a/starlink/ast/test/plothead.py b/starlink/ast/test/plothead.py index b826453..86aba51 100644 --- a/starlink/ast/test/plothead.py +++ b/starlink/ast/test/plothead.py @@ -1,6 +1,5 @@ #!/home/dsb/bin/python3 -from __future__ import print_function import sys @@ -24,7 +23,7 @@ fin2 = open(sys.argv[1] + ".fattr") fits_atts = fin2.read() fin2.close() -except IOError: +except OSError: fits_atts = "" # Attempt to open an associated file holding attributes that control the @@ -34,7 +33,7 @@ fin2 = open(sys.argv[1] + ".attr") plot_atts = fin2.read() fin2.close() -except IOError: +except OSError: plot_atts = "" # Attempt to open an associated file holding the pixel bounds of the @@ -43,7 +42,7 @@ fin2 = open(sys.argv[1] + ".box") box = [float(v) for v in fin2.read().strip().split()] fin2.close() -except IOError: +except OSError: box = None # Read the header lines into a list, and store this list in a new diff --git a/starlink/ast/test/test.py b/starlink/ast/test/test.py index 1f41055..30bb903 100644 --- a/starlink/ast/test/test.py +++ b/starlink/ast/test/test.py @@ -1959,7 +1959,7 @@ def test_ChebyMap(self): if __name__ == "__main__": # starlink.Ast.watchmemory(10914) # unittest.main() - print("Testing pyast version {}\n".format(starlink.Ast.__version__)) + print(f"Testing pyast version {starlink.Ast.__version__}\n") suite = unittest.TestLoader().loadTestsFromTestCase(TestAst) unittest.TextTestRunner(verbosity=2).run(suite) starlink.Ast.activememory("AST memory block still active") diff --git a/starlink/ast/test/test_atl.py b/starlink/ast/test/test_atl.py index eb3994d..fea6ba3 100644 --- a/starlink/ast/test/test_atl.py +++ b/starlink/ast/test/test_atl.py @@ -1,4 +1,3 @@ -from __future__ import print_function try: from astropy.io import fits as pyfits diff --git a/tools/make_attributes.py b/tools/make_attributes.py index 2276b55..0eeabc9 100644 --- a/tools/make_attributes.py +++ b/tools/make_attributes.py @@ -12,7 +12,6 @@ setters that need to be included in th Python TypeObject for the class. """ -from __future__ import print_function import os import os.path @@ -28,7 +27,7 @@ def make_attributes(dirname=None): if dirname is not None: file = os.path.join(dirname, file) - infile = open(file, "r") + infile = open(file) # Read the input file. for line in infile: diff --git a/tools/make_exceptions.py b/tools/make_exceptions.py index e44062a..0f8727b 100644 --- a/tools/make_exceptions.py +++ b/tools/make_exceptions.py @@ -9,7 +9,6 @@ library. """ -from __future__ import print_function import os import os.path @@ -72,7 +71,7 @@ def make_exceptions(dirname=None): # Note that AST__3DFSET is not currently supported because a # variable can not start with a number errcodes = [] - for line in open(errfile, "r"): + for line in open(errfile): words = line.split() if words and words[0] == "enum" and words[2][:5] == "AST__" and words[2][5:6].isalpha(): errcodes.append(words[2][5:]) @@ -84,7 +83,7 @@ def make_exceptions(dirname=None): exit(1) for code in errcodes: - print("static PyObject *{0}_err;".format(code), file=cfile) + print(f"static PyObject *{code}_err;", file=cfile) print( r""" @@ -108,10 +107,10 @@ def make_exceptions(dirname=None): for code in errcodes: print( - ' if( !({0}_err = PyErr_NewException("Ast.{0}", AstError_err, NULL))) return 0;'.format(code), + f' if( !({code}_err = PyErr_NewException("Ast.{code}", AstError_err, NULL))) return 0;', file=cfile, ) - print(' PyDict_SetItemString( dict, "{0}", {0}_err );'.format(code), file=cfile) + print(f' PyDict_SetItemString( dict, "{code}", {code}_err );', file=cfile) print(" ", file=cfile) print( @@ -182,11 +181,11 @@ def make_exceptions(dirname=None): first = True for code in errcodes: if first: - print(" if( status_value == AST__{0} ) {{".format(code), file=cfile) + print(f" if( status_value == AST__{code} ) {{", file=cfile) first = False else: - print(" }} else if( status_value == AST__{0} ) {{".format(code), file=cfile) - print(" PyErr_SetString( {0}_err, message );".format(code), file=cfile) + print(f" }} else if( status_value == AST__{code} ) {{", file=cfile) + print(f" PyErr_SetString( {code}_err, message );", file=cfile) print( """ } else { From 67fa66d34e597fad3141e4164f71c11fe73013c8 Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Sun, 18 Aug 2024 16:32:31 -0700 Subject: [PATCH 6/8] Use open context manager --- tools/make_attributes.py | 207 +++++++++++++++++++-------------------- tools/make_exceptions.py | 165 +++++++++++++++---------------- 2 files changed, 182 insertions(+), 190 deletions(-) diff --git a/tools/make_attributes.py b/tools/make_attributes.py index 0eeabc9..827dee8 100644 --- a/tools/make_attributes.py +++ b/tools/make_attributes.py @@ -27,90 +27,90 @@ def make_attributes(dirname=None): if dirname is not None: file = os.path.join(dirname, file) - infile = open(file) - - # Read the input file. - for line in infile: - - # Ignore blank lines or comment lines - line = line.strip() - if len(line) == 0 or line.startswith("#"): - continue - - # Split the line into comma-separated fields - (classname, attname, readonly, atype, desc, maxindex, minindex, items) = line.split(",") - - # Convert strings to numerical values - minindex = int(minindex) - - # Initialise lists - att_decs = list() - att_descs = list() - - # Convert the fields to more useful types. - items = items.split() - if maxindex == "MXDIM": - maxindex = mxdim - else: - maxindex = int(maxindex) - - # Loop over all indices for multi-valued attributes - for i in range(minindex, maxindex + 1): - - # Loop over all keys for multi-valued attributes - for item in items: - - # Construct the name of the attribute. - aname = attname - if item != "-": - aname += "_" + item - - else: - aname += "_" + str(i) - - # Form the C macro invocation that defines the attribute and append it - # to the list. - mac = "MAKE_GET" + readonly + atype + "(" + classname + "," + aname + ")" - att_decs.append(mac) - - # Form the attribute description to store in the Python TypeObject. - mac = "DEFATT(" + aname + ', "' + desc + '"),' - att_descs.append(mac) - - # Multi-valued attributes can also (usually) be used without any index - # of key. So add an unqualified attribute to the lists. - mac = "MAKE_GET" + readonly + atype + "(" + classname + "," + attname + ")" - att_decs.append(mac) - mac = "DEFATT(" + attname + ', "' + desc + '"),' - att_descs.append(mac) - - # Open the output def file - cfilename = attname + "_def.c" - if dirname is not None: - cfilename = os.path.join(dirname, cfilename) - cfile = open(cfilename, "w") - - # Write out a prologue for the C file - print( - r"""/* + with open(file) as infile: + + # Read the input file. + for line in infile: + + # Ignore blank lines or comment lines + line = line.strip() + if len(line) == 0 or line.startswith("#"): + continue + + # Split the line into comma-separated fields + (classname, attname, readonly, atype, desc, maxindex, minindex, items) = line.split(",") + + # Convert strings to numerical values + minindex = int(minindex) + + # Initialise lists + att_decs = list() + att_descs = list() + + # Convert the fields to more useful types. + items = items.split() + if maxindex == "MXDIM": + maxindex = mxdim + else: + maxindex = int(maxindex) + + # Loop over all indices for multi-valued attributes + for i in range(minindex, maxindex + 1): + + # Loop over all keys for multi-valued attributes + for item in items: + + # Construct the name of the attribute. + aname = attname + if item != "-": + aname += "_" + item + + else: + aname += "_" + str(i) + + # Form the C macro invocation that defines the attribute and append it + # to the list. + mac = "MAKE_GET" + readonly + atype + "(" + classname + "," + aname + ")" + att_decs.append(mac) + + # Form the attribute description to store in the Python TypeObject. + mac = "DEFATT(" + aname + ', "' + desc + '"),' + att_descs.append(mac) + + # Multi-valued attributes can also (usually) be used without any index + # of key. So add an unqualified attribute to the lists. + mac = "MAKE_GET" + readonly + atype + "(" + classname + "," + attname + ")" + att_decs.append(mac) + mac = "DEFATT(" + attname + ', "' + desc + '"),' + att_descs.append(mac) + + # Open the output def file + cfilename = attname + "_def.c" + if dirname is not None: + cfilename = os.path.join(dirname, cfilename) + with open(cfilename, "w") as cfile: + + # Write out a prologue for the C file + print( + r"""/* * Name: * """ - + attname - + "_def.c" - + r""" + + attname + + "_def.c" + + r""" * Purpose: * Declare and define the Python accessor methods for the """ - + attname - + r""" + + attname + + r""" * attribute. * Description: * This file uses the macros defined in pyast.h to define and declare * methods for accessing all the values within the multi-valued AST * attribute """ - + attname - + r""". + + attname + + r""". * Notes: * - This file is generated automatically by the "make_attributes.py" @@ -119,40 +119,39 @@ def make_attributes(dirname=None): */ """, - file=cfile, - ) - - # Write out the attribute declarations, then close the file. - for att in att_decs: - print(att, file=cfile) - cfile.close() - - # Open the output desc file - cfilename = attname + "_desc.c" - if dirname is not None: - cfilename = os.path.join(dirname, cfilename) - cfile = open(cfilename, "w") - - # Write out a prologue for the C file - print( - r"""/* + file=cfile, + ) + + # Write out the attribute declarations, then close the file. + for att in att_decs: + print(att, file=cfile) + + # Open the output desc file + cfilename = attname + "_desc.c" + if dirname is not None: + cfilename = os.path.join(dirname, cfilename) + with open(cfilename, "w") as cfile: + + # Write out a prologue for the C file + print( + r"""/* * Name: * """ - + attname - + "_desc.c" - + r""" + + attname + + "_desc.c" + + r""" * Purpose: * Add entries to the array of Python attribute accessors describing * the """ - + attname - + r""" attribute. + + attname + + r""" attribute. * Description: * This file uses the macros defined in pyast.h to create a description * of the multi-valued AST attribute """ - + attname - + r""" for inclusion in + + attname + + r""" for inclusion in * the array of attribute getters and setters store in the Python * TypeObject for the class. @@ -163,16 +162,12 @@ def make_attributes(dirname=None): */ """, - file=cfile, - ) + file=cfile, + ) - # Write out the attribute dedriptions, then close the file. - for att in att_descs: - print(" " + att, file=cfile) - cfile.close() - - # Close the input file. - infile.close() + # Write out the attribute dedriptions, then close the file. + for att in att_descs: + print(" " + att, file=cfile) if __name__ == "__main__": diff --git a/tools/make_exceptions.py b/tools/make_exceptions.py index 0f8727b..f14a6be 100644 --- a/tools/make_exceptions.py +++ b/tools/make_exceptions.py @@ -31,11 +31,10 @@ def make_exceptions(dirname=None): if dirname is not None: cfilename = os.path.join(dirname, cfilename) - cfile = open(cfilename, "w") - - # Need a C header - print( - r"""/* + with open(cfilename, "w") as cfile: + # Need a C header + print( + r"""/* * Name: * exceptions.c @@ -64,8 +63,8 @@ def make_exceptions(dirname=None): /* For each AST error code, declare a static variable to hold an instance of the corresponding Python Exception. */""", - file=cfile, - ) + file=cfile, + ) # Now read the ast_err.h file and create extract all the error codes # Note that AST__3DFSET is not currently supported because a @@ -76,87 +75,86 @@ def make_exceptions(dirname=None): if words and words[0] == "enum" and words[2][:5] == "AST__" and words[2][5:6].isalpha(): errcodes.append(words[2][5:]) - if not errcodes: - print("Could not find any error codes. Aborting") - cfile.close() - os.path.unlink(cfilename) - exit(1) + if not errcodes: + print("Could not find any error codes. Aborting") + os.path.unlink(cfilename) + exit(1) - for code in errcodes: - print(f"static PyObject *{code}_err;", file=cfile) + for code in errcodes: + print(f"static PyObject *{code}_err;", file=cfile) - print( - r""" + print( + r""" /* Defines a function that creates a Python Exception object - for each AST error code, and uses them to initialises the - above static variables. It reurns 1 if successful, and zero - if an error occurs. */ +for each AST error code, and uses them to initialises the +above static variables. It reurns 1 if successful, and zero +if an error occurs. */ static int RegisterErrors( PyObject *m ){ - PyObject *dict = PyModule_GetDict(m); +PyObject *dict = PyModule_GetDict(m); /* First create an instance of a base AST exception class from which - the other derive. */ - if( !( AstError_err = PyErr_NewException("Ast.AstError", NULL, NULL))) return 0; - PyDict_SetItemString( dict, "AstError", AstError_err ); +the other derive. */ +if( !( AstError_err = PyErr_NewException("Ast.AstError", NULL, NULL))) return 0; +PyDict_SetItemString( dict, "AstError", AstError_err ); /* Now create an instance of each derived AST exception class. */""", - file=cfile, - ) - - for code in errcodes: - print( - f' if( !({code}_err = PyErr_NewException("Ast.{code}", AstError_err, NULL))) return 0;', file=cfile, ) - print(f' PyDict_SetItemString( dict, "{code}", {code}_err );', file=cfile) - print(" ", file=cfile) - print( - r""" return 1; + for code in errcodes: + print( + f' if( !({code}_err = PyErr_NewException("Ast.{code}", AstError_err, NULL))) return 0;', + file=cfile, + ) + print(f' PyDict_SetItemString( dict, "{code}", {code}_err );', file=cfile) + print(" ", file=cfile) + + print( + r""" return 1; } /* The AST library calls this function to deliver an error message - in the form of a Python Exception. For each AST error code, raise - the corresponding Python Exception. */ +in the form of a Python Exception. For each AST error code, raise +the corresponding Python Exception. */ void astPutErr_( int status_value, const char *message ) { /* Local Variables: */ - PyObject *ex; - PyObject *ptype; - PyObject *pvalue; - PyObject *ptraceback; - char *text; - int lstat; - int nc; +PyObject *ex; +PyObject *ptype; +PyObject *pvalue; +PyObject *ptraceback; +char *text; +int lstat; +int nc; /* Clear the AST status value so that AST memory functions will function - properly. */ - lstat = astStatus; - astClearStatus; +properly. */ +lstat = astStatus; +astClearStatus; /* If an AST exception has already occurred, append the new message to it. */ - ex = PyErr_Occurred(); - if( ex ){ - if( PyErr_GivenExceptionMatches( ex, AstError_err ) ) { +ex = PyErr_Occurred(); +if( ex ){ + if( PyErr_GivenExceptionMatches( ex, AstError_err ) ) { /* Get the existing Exception text */ - PyErr_Fetch( &ptype, &pvalue, &ptraceback ); - PyObject *str = PyObject_Str( pvalue ); - text = GetString( NULL, str ); - Py_DECREF(str); - if( text ) { + PyErr_Fetch( &ptype, &pvalue, &ptraceback ); + PyObject *str = PyObject_Str( pvalue ); + text = GetString( NULL, str ); + Py_DECREF(str); + if( text ) { /* Ignore messages that give the C source file and line number since they are - not useful for Python users. */ +not useful for Python users. */ if( strstr( text, "Ast.c" ) ) { - text = astFree( text ); - nc = 0; + text = astFree( text ); + nc = 0; } else { - nc = strlen( text ); - text = astAppendString( text, &nc, "\n" ); + nc = strlen( text ); + text = astAppendString( text, &nc, "\n" ); } /* Append the new message and store the extended text with the Exception. */ @@ -165,40 +163,39 @@ def make_exceptions(dirname=None): pvalue = PyUnicode_FromString( text ); PyErr_Restore( ptype, pvalue, ptraceback); text = astFree( text ); - } - } + } + } /* If an AST or non-AST exception has already occurred, restore the - original AST status value then return without action. */ - astSetStatus( lstat ); - return; - } +original AST status value then return without action. */ + astSetStatus( lstat ); + return; +} /* If no exception has already occurred, raise an appropriate AST exception now. */""", - file=cfile, - ) - - first = True - for code in errcodes: - if first: - print(f" if( status_value == AST__{code} ) {{", file=cfile) - first = False - else: - print(f" }} else if( status_value == AST__{code} ) {{", file=cfile) - print(f" PyErr_SetString( {code}_err, message );", file=cfile) - - print( - """ } else { - PyErr_SetString( AstError_err, message ); - } + file=cfile, + ) + + first = True + for code in errcodes: + if first: + print(f" if( status_value == AST__{code} ) {{", file=cfile) + first = False + else: + print(f" }} else if( status_value == AST__{code} ) {{", file=cfile) + print(f" PyErr_SetString( {code}_err, message );", file=cfile) + + print( + """ } else { + PyErr_SetString( AstError_err, message ); +} /* restore the original AST status value. */ - astSetStatus( lstat ); +astSetStatus( lstat ); } """, - file=cfile, - ) - cfile.close() + file=cfile, + ) if __name__ == "__main__": From e6d1b7068d368aa19e3db4fba44d1c2205014199 Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Sun, 18 Aug 2024 16:41:27 -0700 Subject: [PATCH 7/8] Use with open --- starlink/ast/test/plothead.py | 70 ++++++++++++++++------------------- starlink/ast/test/test_atl.py | 1 - 2 files changed, 32 insertions(+), 39 deletions(-) diff --git a/starlink/ast/test/plothead.py b/starlink/ast/test/plothead.py index 86aba51..0e6f672 100644 --- a/starlink/ast/test/plothead.py +++ b/starlink/ast/test/plothead.py @@ -14,44 +14,38 @@ sys.exit(2) # Attempt to open the header file -fin1 = open(sys.argv[1] + ".head") - -# Attempt to open an associated file holding attributes that control how -# the FITS headers are interpreted. If succesful, read the whole file into -# a single string. -try: - fin2 = open(sys.argv[1] + ".fattr") - fits_atts = fin2.read() - fin2.close() -except OSError: - fits_atts = "" - -# Attempt to open an associated file holding attributes that control the -# appearance of the plot. If successful, read the whole file into a -# single string. -try: - fin2 = open(sys.argv[1] + ".attr") - plot_atts = fin2.read() - fin2.close() -except OSError: - plot_atts = "" - -# Attempt to open an associated file holding the pixel bounds of the -# area of the FITS array to be plotted. -try: - fin2 = open(sys.argv[1] + ".box") - box = [float(v) for v in fin2.read().strip().split()] - fin2.close() -except OSError: - box = None - -# Read the header lines into a list, and store this list in a new -# Ast.FitsChan, using the requested attributes to modify the -# interpretation of the header. -fc = Ast.FitsChan(fin1.readlines(), None, fits_atts) - -# Close the header file. -fin1.close() +with open(sys.argv[1] + ".head") as fin1: + + # Attempt to open an associated file holding attributes that control how + # the FITS headers are interpreted. If succesful, read the whole file into + # a single string. + try: + with open(sys.argv[1] + ".fattr") as fin2: + fits_atts = fin2.read() + except OSError: + fits_atts = "" + + # Attempt to open an associated file holding attributes that control the + # appearance of the plot. If successful, read the whole file into a + # single string. + try: + with open(sys.argv[1] + ".attr") as fin2: + plot_atts = fin2.read() + except OSError: + plot_atts = "" + + # Attempt to open an associated file holding the pixel bounds of the + # area of the FITS array to be plotted. + try: + with open(sys.argv[1] + ".box") as fin2: + box = [float(v) for v in fin2.read().strip().split()] + except OSError: + box = None + + # Read the header lines into a list, and store this list in a new + # Ast.FitsChan, using the requested attributes to modify the + # interpretation of the header. + fc = Ast.FitsChan(fin1.readlines(), None, fits_atts) # Create a FrameSet from the FITS headers in the FitsChan. fs = fc.read() diff --git a/starlink/ast/test/test_atl.py b/starlink/ast/test/test_atl.py index fea6ba3..25c9ec5 100644 --- a/starlink/ast/test/test_atl.py +++ b/starlink/ast/test/test_atl.py @@ -1,4 +1,3 @@ - try: from astropy.io import fits as pyfits except ImportError: From 507e40e72a3f93163f688bd377d61eb201d096f4 Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Sun, 18 Aug 2024 16:57:10 -0700 Subject: [PATCH 8/8] fixup! Use open context manager --- tools/make_exceptions.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tools/make_exceptions.py b/tools/make_exceptions.py index f14a6be..1c34825 100644 --- a/tools/make_exceptions.py +++ b/tools/make_exceptions.py @@ -66,18 +66,19 @@ def make_exceptions(dirname=None): file=cfile, ) - # Now read the ast_err.h file and create extract all the error codes - # Note that AST__3DFSET is not currently supported because a - # variable can not start with a number - errcodes = [] - for line in open(errfile): - words = line.split() - if words and words[0] == "enum" and words[2][:5] == "AST__" and words[2][5:6].isalpha(): - errcodes.append(words[2][5:]) + # Now read the ast_err.h file and create extract all the error codes + # Note that AST__3DFSET is not currently supported because a + # variable can not start with a number + errcodes = [] + with open(errfile) as errfd: + for line in errfd: + words = line.split() + if words and words[0] == "enum" and words[2][:5] == "AST__" and words[2][5:6].isalpha(): + errcodes.append(words[2][5:]) if not errcodes: - print("Could not find any error codes. Aborting") - os.path.unlink(cfilename) + print(f"Could not find any error codes in {errfile}. Aborting") + os.unlink(cfilename) exit(1) for code in errcodes: