Skip to content

Commit

Permalink
Merge pull request #15480 from meeseeksmachine/auto-backport-of-pr-15…
Browse files Browse the repository at this point in the history
…473-on-v5.3.x

Backport PR #15473 on branch v5.3.x (Ensure tables with masked and unmasked columns roundtrip properly)
  • Loading branch information
pllim committed Oct 13, 2023
2 parents 6d9760b + f965ba1 commit a4000af
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 6 deletions.
11 changes: 6 additions & 5 deletions astropy/io/fits/convenience.py
Original file line number Diff line number Diff line change
Expand Up @@ -541,12 +541,13 @@ def table_to_hdu(table, character_as_bytes=False):
# Binary FITS tables support TNULL *only* for integer data columns
# TODO: Determine a schema for handling non-integer masked columns
# with non-default fill values in FITS (if at all possible).
# Be careful that we do not set null for columns that were not masked!
int_formats = ("B", "I", "J", "K")
if not (col.format in int_formats or col.format.p_format in int_formats):
continue

fill_value = tarray[col.name].fill_value
col.null = fill_value.astype(int)
if (
col.format in int_formats or col.format.p_format in int_formats
) and hasattr(table[col.name], "mask"):
fill_value = tarray[col.name].fill_value
col.null = fill_value.astype(int)
else:
table_hdu = BinTableHDU.from_columns(
tarray, header=hdr, character_as_bytes=character_as_bytes
Expand Down
14 changes: 13 additions & 1 deletion astropy/io/fits/tests/test_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
python_to_tdisp,
)
from astropy.io.tests.mixin_columns import compare_attrs, mixin_cols, serialized_names
from astropy.table import Column, QTable, Table
from astropy.table import Column, MaskedColumn, QTable, Table
from astropy.table.table_helpers import simple_table
from astropy.time import Time
from astropy.units import allclose as quantity_allclose
Expand Down Expand Up @@ -1069,3 +1069,15 @@ def test_meta_not_modified(tmp_path):
def test_is_fits_gh_14305():
"""Regression test for https://github.com/astropy/astropy/issues/14305"""
assert not connect.is_fits("", "foo.bar", None)


def test_keep_masked_state_integer_columns(tmp_path):
"""Regression test for https://github.com/astropy/astropy/issues/15417"""
filename = tmp_path / "test_masked.fits"
t = Table([[1, 2], [1.5, 2.5]], names=["a", "b"])
t["c"] = MaskedColumn([1, 2], mask=[True, False])
t.write(filename)
tr = Table.read(filename)
assert not isinstance(tr["a"], MaskedColumn)
assert not isinstance(tr["b"], MaskedColumn)
assert isinstance(tr["c"], MaskedColumn)
3 changes: 3 additions & 0 deletions docs/changes/io.fits/15473.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Ensure that tables written to FITS with both masked and unmasked columns
roundtrip properly (previously, all integer columns would become masked
if any column was masked).

0 comments on commit a4000af

Please sign in to comment.