Skip to content

Commit

Permalink
Merge b83bd55 into db84b63
Browse files Browse the repository at this point in the history
  • Loading branch information
JonahDW committed May 18, 2020
2 parents db84b63 + b83bd55 commit 707dc76
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 31 deletions.
2 changes: 1 addition & 1 deletion docs/crtf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Serialisation is done using the `~regions.crtf_objects_to_string` function
>>> from regions import crtf_objects_to_string
>>> crtf_objects_to_string(regions, coordsys='galactic')
'#CRTF\ncircle[[144.559169deg, -14.923593deg], 3.000000deg], coord=GALACTIC, color=green\n'
'#CRTFv0\nglobal coord=GALACTIC\ncircle[[144.559169deg, -14.923593deg], 3.000000deg], color=green\n'
There's also `~regions.write_crtf` and `~regions.read_crtf` which write to and
read from a file in addition to doing the region serialisation and parsing.
Expand Down
40 changes: 24 additions & 16 deletions regions/io/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,15 @@ class RegionConversionError(ValueError):

# Maps astropy's coordinate frame names with their respective name in the file format.
coordsys_mapping = {'DS9': {x: x for x in valid_coordsys['DS9']},
'CRTF': {x: x for x in valid_coordsys['CRTF']}
'CRTF': {x: x.upper() for x in valid_coordsys['CRTF']}
}
coordsys_mapping['CRTF']['geocentrictrueecliptic'] = 'ecliptic'
coordsys_mapping['CRTF']['fk5'] = 'j2000'
coordsys_mapping['CRTF']['fk4'] = 'b1950'
coordsys_mapping['CRTF']['supergalactic'] = 'supergal'
# Coordinate frame names must be uppercase following the CASA CRTF syntax
coordsys_mapping['CRTF']['geocentrictrueecliptic'] = 'ECLIPTIC'
coordsys_mapping['CRTF']['fk5'] = 'J2000'
coordsys_mapping['CRTF']['fk4'] = 'B1950'
coordsys_mapping['CRTF']['supergalactic'] = 'SUPERGAL'

coordsys_mapping['DS9']['geocentrictrueecliptic'] = 'ecliptic'
coordsys_mapping['DS9']['geocentrictrueecliptic'] = 'ECLIPTIC'


class ShapeList(list):
Expand Down Expand Up @@ -128,7 +129,8 @@ def to_crtf(self, coordsys='fk5', fmt='.6f', radunit='deg'):
crtf_strings = {
'circle': '{0}circle[[{1:FMT}deg, {2:FMT}deg], {3:FMT}RAD]',
'circleannulus': '{0}annulus[[{1:FMT}deg, {2:FMT}deg], [{3:FMT}RAD, {4:FMT}RAD]]',
'ellipse': '{0}ellipse[[{1:FMT}deg, {2:FMT}deg], [{3:FMT}RAD, {4:FMT}RAD], {5:FMT}deg]',
# Make sure that width goes to minor axis and height to major axis
'ellipse': '{0}ellipse[[{1:FMT}deg, {2:FMT}deg], [{4:FMT}RAD, {3:FMT}RAD], {5:FMT}deg]',
'rectangle': '{0}rotbox[[{1:FMT}deg, {2:FMT}deg], [{3:FMT}RAD, {4:FMT}RAD], {5:FMT}deg]',
'polygon': '{0}poly[{1}]',
'point': '{0}point[[{1:FMT}deg, {2:FMT}deg]]',
Expand All @@ -137,11 +139,11 @@ def to_crtf(self, coordsys='fk5', fmt='.6f', radunit='deg'):
'line': '{0}line[[{1:FMT}deg, {2:FMT}deg], [{3:FMT}deg, {4:FMT}deg]]'
}

output = '#CRTF\n'
output = '#CRTFv0\n'

if radunit == 'arcsec':
# what's this for?
if coordsys in coordsys_mapping['CRTF'].values():
# arcseconds are allowed for all but image coordinates
if coordsys.lower() not in ('image',):
radunitstr = '"'
else:
raise ValueError(
Expand All @@ -156,7 +158,7 @@ def to_crtf(self, coordsys='fk5', fmt='.6f', radunit='deg'):

# CASA does not support global coordinate specification, even though the
# documentation for the specification explicitly states that it does.
# output += 'global coord={}\n'.format(coordsys)
output += 'global coord={}\n'.format(coordsys_mapping['CRTF'][coordsys.lower()])

for shape in self:

Expand All @@ -173,15 +175,21 @@ def to_crtf(self, coordsys='fk5', fmt='.6f', radunit='deg'):
if shape.meta.get('label', "") != "":
shape.meta['label'] = "'{}'".format(shape.meta['label'])
meta_str = ", ".join(f"{key}={val}" for key, val in
shape.meta.items() if
key not in ('include', 'comment', 'symbol',
'coord', 'text', 'range', 'corr',
'type'))
shape.meta.items() if
key not in ('include', 'comment', 'symbol',
'coord', 'text', 'range', 'corr',
'type'))

# the first item should be the coordinates, since CASA cannot
# recognize a region without an inline coordinate specification
# It can be, but does not need to be, comma-separated at the start
meta_str = "coord={}, ".format(coordsys.upper()) + meta_str
shape_coordsys = getattr(shape, 'coordsys')
if shape_coordsys.lower() != coordsys.lower():
if meta_str.strip():
meta_str = "coord={}, ".format(coordsys_mapping['CRTF'][coordsys.lower()]) + meta_str
else:
# if there is no metadata at all (above), the trailing comma is incorrect
meta_str = "coord={}".format(coordsys_mapping['CRTF'][coordsys.lower()])

if 'comment' in shape.meta:
meta_str += ", " + shape.meta['comment']
Expand Down
2 changes: 2 additions & 0 deletions regions/io/crtf/read.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,8 @@ def make_shape(self):
"""
if self.region_type == 'ellipse':
self.coord[2:] = [x * 2 for x in self.coord[2:]]
# Map major and minor axis to height and width respectively
self.coord[2], self.coord[3] = self.coord[3], self.coord[2]
if len(self.coord) % 2 == 1: # This checks if the angle is present.
self.coord[-1] /= 2

Expand Down
2 changes: 1 addition & 1 deletion regions/io/crtf/tests/data/CRTFgeneral.crtf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#CRTF0
#CRTFv0
global coord=B1950, frame=BARY, corr=[I, Q], color=blue

# A simple circle region:
Expand Down
17 changes: 9 additions & 8 deletions regions/io/crtf/tests/data/CRTFgeneraloutput.crtf
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#CRTF
ann circle[[273.100deg, -23.183deg], 0.001deg], coord=FK4, frame=BARY, color=blue, corr=[I, Q]
rotbox[[180.392deg, 12.392deg], [0.050deg, 0.017deg], 12.000deg], coord=FK4, frame=BARY, color=blue, range=[-1240.0km/s, 1240.0km/s], corr=[I, Q]
annulus[[267.763deg, -45.297deg], [0.100deg, 4.120deg]], coord=FK4, label='My label here', frame=BARY, color=red, corr=[I, Q, U, V]
-ellipse[[12.000deg, 45.000deg], [0.250deg, 1.340deg], 2578.310deg], coord=FK4, label='Removed this', frame=BARY, color=green, range=[1.42GHz, 1.421GHz], corr=[Q]
symbol[[31.470deg, 11.905deg], D], coord=FK4, frame=BARY, color=blue, linewidth=2, symsize=2, corr=[I, Q]
text[[31.470deg, 11.905deg], 'my text'], coord=FK4, frame=BARY, color=blue, linewidth=2, corr=[I, Q]
rotbox[[2.000deg, 3.000deg], [2.000deg, 2.000deg], 0.000deg], coord=FK4, frame=BARY, color=blue, corr=[I, Q]
#CRTFv0
global coord=B1950
ann circle[[273.100deg, -23.183deg], 0.001deg], frame=BARY, color=blue, corr=[I, Q]
rotbox[[180.392deg, 12.392deg], [0.050deg, 0.017deg], 12.000deg], frame=BARY, color=blue, range=[-1240.0km/s, 1240.0km/s], corr=[I, Q]
annulus[[267.763deg, -45.297deg], [0.100deg, 4.120deg]], label='My label here', frame=BARY, color=red, corr=[I, Q, U, V]
-ellipse[[12.000deg, 45.000deg], [0.250deg, 1.340deg], 2578.310deg], label='Removed this', frame=BARY, color=green, range=[1.42GHz, 1.421GHz], corr=[Q]
symbol[[31.470deg, 11.905deg], D], frame=BARY, color=blue, linewidth=2, symsize=2, corr=[I, Q]
text[[31.470deg, 11.905deg], 'my text'], frame=BARY, color=blue, linewidth=2, corr=[I, Q]
rotbox[[2.000deg, 3.000deg], [2.000deg, 2.000deg], 0.000deg], frame=BARY, color=blue, corr=[I, Q]
16 changes: 16 additions & 0 deletions regions/io/crtf/tests/test_crtf_language.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@
import astropy.version as astrov
from astropy.utils.data import get_pkg_data_filename

from astropy import coordinates, units as u


from ..read import CRTFParser, read_crtf
from ..write import crtf_objects_to_string
from ..core import CRTFRegionParserError

from ....shapes.ellipse import EllipseSkyRegion

_ASTROPY_MINVERSION = vers.LooseVersion('1.1')
_ASTROPY_VERSION = vers.LooseVersion(astrov.version)

Expand Down Expand Up @@ -123,6 +127,18 @@ def test_valid_region_syntax():

assert "('3arcmin', '') should be a pair of length" in str(excinfo.value)

def test_issue_312_regression():
"""
Make sure there is no trailing comma when writing a CRTF string with no metadata
"""
reg = EllipseSkyRegion(center=coordinates.SkyCoord(279.174990*u.deg,
-21.257123*u.deg,
frame='fk5'),
width=0.001571*u.deg, height=0.001973*u.deg,
angle=111.273322*u.deg)
crtfstr = crtf_objects_to_string([reg], 'fk5', '.6f', 'deg')
assert crtfstr.strip()[-1] != ','


@pytest.mark.parametrize('filename', ['data/CRTFgeneral.crtf', 'data/CRTFgeneraloutput.crtf'])
def test_file_crtf(filename):
Expand Down
7 changes: 4 additions & 3 deletions regions/io/crtf/write.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def crtf_objects_to_string(regions, coordsys='fk5', fmt='.6f', radunit='deg'):
List of `~regions.Region` objects
coordsys : `str`, optional
Astropy Coordinate system that overrides the coordinate system frame for
all regions. Default is 'fk5'.
all regions. Default is 'fk5' (which maps to J2000).
fmt : `str`, optional
A python string format defining the output precision. Default is .6f,
which is accurate to 0.0036 arcseconds.
Expand All @@ -36,8 +36,9 @@ def crtf_objects_to_string(regions, coordsys='fk5', fmt='.6f', radunit='deg'):
>>> from regions import CircleSkyRegion, crtf_objects_to_string
>>> reg_sky = CircleSkyRegion(SkyCoord(1 * u.deg, 2 * u.deg), 5 * u.deg)
>>> print(crtf_objects_to_string([reg_sky]))
#CRTF
circle[[1.000007deg, 2.000002deg], 5.000000deg], coord=FK5,
#CRTFv0
global coord=J2000
circle[[1.000007deg, 2.000002deg], 5.000000deg]
"""
shapelist = to_shape_list(regions, coordsys)
Expand Down
4 changes: 2 additions & 2 deletions regions/io/tests/test_shape_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ def test_valid_ellipse_crtf():
assert_quantity_allclose(shape1.coord[:2], [1, 2])
assert_quantity_allclose(shape2.coord[:2], [Quantity("1deg"), Quantity("2deg")])

assert_quantity_allclose(shape1.coord[2:-1], [6, 8])
assert_quantity_allclose(shape2.coord[2:-1], [Quantity("6deg"), Quantity("8deg")])
assert_quantity_allclose(shape1.coord[2:-1], [8, 6])
assert_quantity_allclose(shape2.coord[2:-1], [Quantity("8deg"), Quantity("6deg")])

assert_quantity_allclose(shape1.coord[-1], Quantity("5deg"))
assert_quantity_allclose(shape2.coord[-1], Quantity("5deg"))

0 comments on commit 707dc76

Please sign in to comment.