Skip to content

Writing a Table with a SkyCoord mixin fails when SkyCoord is created from a list of SkyCoord #6446

Closed

Description

@larrybradley

This fails:

from astropy.coordinates import SkyCoord
from astropy.table import Table

c1 = SkyCoord(1, 3, unit='deg')
c2 = SkyCoord(2, 4, unit='deg')
sc1 = SkyCoord([c1, c2])
t = Table([sc1])
t.write('mixin.ecsv', format='ascii.ecsv', overwrite=True)

But this works fine:

from astropy.coordinates import SkyCoord
from astropy.table import Table

sc2 = SkyCoord([1, 2], [3, 4], unit='deg')
t2 = Table([sc2])
t2.write('mixin.ecsv', format='ascii.ecsv', overwrite=True)

So, sc1 and sc2 are different(!) in some way for the Table writer. I tracked this down to
sc1 somehow having its galcen_v_sun attribute set(?!):

>>> sc1.galcen_v_sun
<CartesianDifferential (d_x, d_y, d_z) in km / s
    ( 11.1,  232.24,  7.25)>

>>> sc2.galcen_v_sun

So it appears that the Table writer cannot serialize SkyCoord objects with galcen_v_sun attributes, and I don't know why this attribute is set when initializing a SkyCoord object from a list of SkyCoord objects. Are these both bugs?

Here's the traceback for the first example, showing the galcen_v_sun values in the raised error message
(RepresenterError: cannot represent an object: ( 11.1, 232.24, 7.25) km / s):

---------------------------------------------------------------------------
RepresenterError                          Traceback (most recent call last)
<ipython-input-68-df4a66266376> in <module>()
      6 sc1 = SkyCoord([c1, c2])
      7 t = Table([sc1])
----> 8 t.write('mixin.ecsv', format='ascii.ecsv', overwrite=True)

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/table/table.py in write(self, *args, **kwargs)
   2548         passed through to the underlying data reader (e.g. `~astropy.io.ascii.write`).
   2549         """
-> 2550         io_registry.write(self, *args, **kwargs)
   2551 
   2552     def copy(self, copy_data=True):

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/io/registry.py in write(data, *args, **kwargs)
    579 
    580     writer = get_writer(format, data.__class__)
--> 581     writer(data, *args, **kwargs)
    582 
    583 

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/io/ascii/connect.py in io_write(format, table, filename, **kwargs)
     43     from .ui import write
     44     format = re.sub(r'^ascii\.', '', format)
---> 45     return write(table, filename, format=format, **kwargs)
     46 
     47 

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/io/ascii/ui.py in write(table, output, format, Writer, fast_writer, **kwargs)
    733         return
    734 
--> 735     lines = writer.write(table)
    736 
    737     # Write the lines to output

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/io/ascii/core.py in write(self, table)
   1310         # Write header and data to lines list
   1311         lines = []
-> 1312         self.write_header(lines, table.meta)
   1313         self.data.write(lines)
   1314 

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/io/ascii/core.py in write_header(self, lines, meta)
   1269     def write_header(self, lines, meta):
   1270         self.header.write_comments(lines, meta)
-> 1271         self.header.write(lines)
   1272 
   1273     def write(self, table):

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/io/ascii/ecsv.py in write(self, lines)
     72         header_yaml_lines = (['%ECSV {0}'.format(ECSV_VERSION),
     73                               '---']
---> 74                              + meta.get_yaml_from_header(header))
     75 
     76         lines.extend([self.write_comment + line for line in header_yaml_lines])

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/table/meta.py in get_yaml_from_header(header)
    288     del header['cols']
    289 
--> 290     lines = yaml.dump(header, Dumper=TableDumper).splitlines()
    291     return lines
    292 

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/__init__.py in dump(data, stream, Dumper, **kwds)
    198     If stream is None, return the produced string instead.
    199     """
--> 200     return dump_all([data], stream, Dumper=Dumper, **kwds)
    201 
    202 def safe_dump_all(documents, stream=None, **kwds):

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/__init__.py in dump_all(documents, stream, Dumper, default_style, default_flow_style, canonical, indent, width, allow_unicode, line_break, encoding, explicit_start, explicit_end, version, tags)
    186         dumper.open()
    187         for data in documents:
--> 188             dumper.represent(data)
    189         dumper.close()
    190     finally:

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/representer.py in represent(self, data)
     24 
     25     def represent(self, data):
---> 26         node = self.represent_data(data)
     27         self.serialize(node)
     28         self.represented_objects = {}

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/representer.py in represent_data(self, data)
     45         data_types = type(data).__mro__
     46         if data_types[0] in self.yaml_representers:
---> 47             node = self.yaml_representers[data_types[0]](self, data)
     48         else:
     49             for data_type in data_types:

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/representer.py in represent_dict(self, data)
    203 
    204     def represent_dict(self, data):
--> 205         return self.represent_mapping('tag:yaml.org,2002:map', data)
    206 
    207     def represent_set(self, data):

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/table/meta.py in represent_mapping(self, tag, mapping, flow_style)
    268             for item_key, item_value in mapping:
    269                 node_key = self.represent_data(item_key)
--> 270                 node_value = self.represent_data(item_value)
    271                 if not (isinstance(node_key, yaml.ScalarNode) and not node_key.style):
    272                     best_style = False

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/representer.py in represent_data(self, data)
     45         data_types = type(data).__mro__
     46         if data_types[0] in self.yaml_representers:
---> 47             node = self.yaml_representers[data_types[0]](self, data)
     48         else:
     49             for data_type in data_types:

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/table/meta.py in _repr_odict(dumper, data)
    145     '!!omap [foo: bar, mumble: quux, baz: gorp]\\n'
    146     """
--> 147     return _repr_pairs(dumper, u'tag:yaml.org,2002:omap', six.iteritems(data))
    148 
    149 

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/table/meta.py in _repr_pairs(dump, tag, sequence, flow_style)
    120     best_style = True
    121     for (key, val) in sequence:
--> 122         item = dump.represent_data({key: val})
    123         if not (isinstance(item, yaml.ScalarNode) and not item.style):
    124             best_style = False

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/representer.py in represent_data(self, data)
     45         data_types = type(data).__mro__
     46         if data_types[0] in self.yaml_representers:
---> 47             node = self.yaml_representers[data_types[0]](self, data)
     48         else:
     49             for data_type in data_types:

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/representer.py in represent_dict(self, data)
    203 
    204     def represent_dict(self, data):
--> 205         return self.represent_mapping('tag:yaml.org,2002:map', data)
    206 
    207     def represent_set(self, data):

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/table/meta.py in represent_mapping(self, tag, mapping, flow_style)
    268             for item_key, item_value in mapping:
    269                 node_key = self.represent_data(item_key)
--> 270                 node_value = self.represent_data(item_value)
    271                 if not (isinstance(node_key, yaml.ScalarNode) and not node_key.style):
    272                     best_style = False

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/representer.py in represent_data(self, data)
     45         data_types = type(data).__mro__
     46         if data_types[0] in self.yaml_representers:
---> 47             node = self.yaml_representers[data_types[0]](self, data)
     48         else:
     49             for data_type in data_types:

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/representer.py in represent_dict(self, data)
    203 
    204     def represent_dict(self, data):
--> 205         return self.represent_mapping('tag:yaml.org,2002:map', data)
    206 
    207     def represent_set(self, data):

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/table/meta.py in represent_mapping(self, tag, mapping, flow_style)
    268             for item_key, item_value in mapping:
    269                 node_key = self.represent_data(item_key)
--> 270                 node_value = self.represent_data(item_value)
    271                 if not (isinstance(node_key, yaml.ScalarNode) and not node_key.style):
    272                     best_style = False

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/representer.py in represent_data(self, data)
     45         data_types = type(data).__mro__
     46         if data_types[0] in self.yaml_representers:
---> 47             node = self.yaml_representers[data_types[0]](self, data)
     48         else:
     49             for data_type in data_types:

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/representer.py in represent_dict(self, data)
    203 
    204     def represent_dict(self, data):
--> 205         return self.represent_mapping('tag:yaml.org,2002:map', data)
    206 
    207     def represent_set(self, data):

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/astropy/table/meta.py in represent_mapping(self, tag, mapping, flow_style)
    268             for item_key, item_value in mapping:
    269                 node_key = self.represent_data(item_key)
--> 270                 node_value = self.represent_data(item_value)
    271                 if not (isinstance(node_key, yaml.ScalarNode) and not node_key.style):
    272                     best_style = False

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/representer.py in represent_data(self, data)
     55                     node = self.yaml_multi_representers[None](self, data)
     56                 elif None in self.yaml_representers:
---> 57                     node = self.yaml_representers[None](self, data)
     58                 else:
     59                     node = ScalarNode(None, str(data))

~/local/conda/envs/photutils-dev/lib/python3.6/site-packages/yaml/representer.py in represent_undefined(self, data)
    227 
    228     def represent_undefined(self, data):
--> 229         raise RepresenterError("cannot represent an object: %s" % data)
    230 
    231 SafeRepresenter.add_representer(type(None),

RepresenterError: cannot represent an object: ( 11.1,  232.24,  7.25) km / s

CC: @eteq, @taldcroft

Activity

  1. eteq commented on Aug 15, 2017

    @eteq
    Member

    This one's a doozy, bit I figured it out. PR incoming shortly! (#6448)

  2. eteq commented on Aug 15, 2017

    @eteq
    Member

    Oh and note this is effectively 2 separate bugs:

    1. galcen_v_sun is getting set at all in this case
    2. galcen_v_sun does not get represented properly in ecsv

    I'm going to decide that this issue is about 1 (which is a lot easier to fix), but make a separate issue for 2.

  3. added a commit that references this issue on Aug 15, 2017
  4. added a commit that references this issue on Sep 5, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions