Search code examples
pythonastropyphotutils

How to save a QTable to a file (.txt, .csv, etc.)


I am trying to save a QTable object which originates from a Isophote list of an elliptical isophote fit, to really any filetype (.txt, .csv, etc.) that allows me to simply just load it back into the script without having to clean it or any of that sorts.

  • The QTable is created as follows:
example_isolist = ellipse_example.fit_image(sclip=3., nclip=3) #performing elliptical isophote fit and creating the Isophote list
example_isolist_tab = example_isolist.to_table() #converting to QTable
  • My attempt:
import json
with open("example_isolist_tab.txt", 'w') as f:
    json.dump(example_isolist_tab, f, indent=2)

Using json here does not work. The following error occurrs:

TypeError: Object of type QTable is not JSON serializable

Anybody here got experience with photutils data handling or saving an isophote fit to a file ? It should be a very simple thing really, just a way so I don't have to rerun my entire script each time I want to work with the results from the isophote fit. My whole data set contains 26 images which would mean roughly 2.5h computation time without saving in between.

Thanks in advance!


Solution

  • Astropy already has numerous built-in formats for saving Tables with Table.write.

    For QTable in particular, if you want a round-trippable text-based format the ECSV format is highly recommended, as it also outputs metadata concerning each column's types and units. If you name your file with a .ecsv extension, this format is used automatically. For example:

    >>> from astropy.table import QTable
    >>> import astropy.units as u
    >>> import numpy as np
    
    >>> a = np.array([1, 4, 5], dtype=np.int32)
    >>> b = [2.0, 5.0, 8.5]
    >>> c = ['x', 'y', 'z']
    >>> d = [10, 20, 30] * u.m / u.s
    
    >>> t = QTable([a, b, c, d],
    ...            names=('a', 'b', 'c', 'd'),
    ...            meta={'name': 'first table'})
    
    >>> t.write('table.ecsv')
    
    >>>  print(open('table.ecsv').read())
    # %ECSV 0.9
    # ---
    # datatype:
    # - {name: a, datatype: int32}
    # - {name: b, datatype: float64}
    # - {name: c, datatype: string}
    # - {name: d, unit: m / s, datatype: float64}
    # meta:
    #   __serialized_columns__:
    #     d:
    #       __class__: astropy.units.quantity.Quantity
    #       unit: !astropy.units.Unit {unit: m / s}
    #       value: !astropy.table.SerializedColumn {name: d}
    #   name: first table
    # schema: astropy-2.0
    a b c d
    1 2.0 x 10.0
    4 5.0 y 20.0
    5 8.5 z 30.0
    
    >>> QTable.read('table.ecsv')
    <QTable length=3>
      a      b     c      d   
                        m / s 
    int32 float64 str1 float64
    ----- ------- ---- -------
        1     2.0    x    10.0
        4     5.0    y    20.0
        5     8.5    z    30.0