Skip to content

Commit 02b24d3

Browse files
astrofrogpull[bot]
authored andcommitted
Simplify CompImageHeader but keep it to still check for reserved keywords
1 parent c3763ee commit 02b24d3

1 file changed

Lines changed: 4 additions & 181 deletions

File tree

‎astropy/io/fits/hdu/compressed/header.py‎

Lines changed: 4 additions & 181 deletions
Original file line numberDiff line numberDiff line change
@@ -70,31 +70,6 @@ class CompImageHeader(Header):
7070
["ZIMAGE", "ZCMPTYPE", "ZMASKCMP", "ZQUANTIZ", "ZDITHER0"]
7171
)
7272
_indexed_compression_keywords = {"ZNAXIS", "ZTILE", "ZNAME", "ZVAL"}
73-
# TODO: Once it place it should be possible to manage some of this through
74-
# the schema system, but it's not quite ready for that yet. Also it still
75-
# makes more sense to change CompImageHDU to subclass ImageHDU :/
76-
77-
def __new__(cls, table_header, image_header=None):
78-
# 2019-09-14 (MHvK): No point wrapping anything if no image_header is
79-
# given. This happens if __getitem__ and copy are called - our super
80-
# class will aim to initialize a new, possibly partially filled
81-
# header, but we cannot usefully deal with that.
82-
# TODO: the above suggests strongly we should *not* subclass from
83-
# Header. See also comment above about the need for reorganization.
84-
if image_header is None:
85-
return Header(table_header)
86-
else:
87-
return super().__new__(cls)
88-
89-
def __init__(self, table_header, image_header):
90-
self._cards = image_header._cards
91-
self._keyword_indices = image_header._keyword_indices
92-
self._rvkc_indices = image_header._rvkc_indices
93-
self._modified = image_header._modified
94-
self._table_header = table_header
95-
96-
# We need to override and Header methods that can modify the header, and
97-
# ensure that they sync with the underlying _table_header
9873

9974
def __setitem__(self, key, value):
10075
# This isn't pretty, but if the `key` is either an int or a tuple we
@@ -119,38 +94,6 @@ def __setitem__(self, key, value):
11994

12095
super().__setitem__(key, value)
12196

122-
if index is not None:
123-
remapped_keyword = self._remap_keyword(keyword)
124-
self._table_header[remapped_keyword, index] = value
125-
# Else this will pass through to ._update
126-
127-
def __delitem__(self, key):
128-
if isinstance(key, slice) or self._haswildcard(key):
129-
# If given a slice pass that on to the superclass and bail out
130-
# early; we only want to make updates to _table_header when given
131-
# a key specifying a single keyword
132-
return super().__delitem__(key)
133-
134-
if isinstance(key, int):
135-
keyword, index = self._keyword_from_index(key)
136-
elif isinstance(key, tuple):
137-
keyword, index = key
138-
else:
139-
keyword, index = key, None
140-
141-
if key not in self:
142-
raise KeyError(f"Keyword {key!r} not found.")
143-
144-
super().__delitem__(key)
145-
146-
remapped_keyword = self._remap_keyword(keyword)
147-
148-
if remapped_keyword in self._table_header:
149-
if index is not None:
150-
del self._table_header[(remapped_keyword, index)]
151-
else:
152-
del self._table_header[remapped_keyword]
153-
15497
def append(self, card=None, useblanks=True, bottom=False, end=False):
15598
# This logic unfortunately needs to be duplicated from the base class
15699
# in order to determine the keyword
@@ -163,32 +106,14 @@ def append(self, card=None, useblanks=True, bottom=False, end=False):
163106
elif not isinstance(card, Card):
164107
raise ValueError(
165108
"The value appended to a Header must be either a keyword or "
166-
f"(keyword, value, [comment]) tuple; got: {card!r}"
109+
"(keyword, value, [comment]) tuple; got: {!r}".format(card)
167110
)
168111

169112
if self._is_reserved_keyword(card.keyword):
170113
return
171114

172115
super().append(card=card, useblanks=useblanks, bottom=bottom, end=end)
173116

174-
remapped_keyword = self._remap_keyword(card.keyword)
175-
176-
# card.keyword strips the HIERARCH if present so this must be added
177-
# back to avoid a warning.
178-
if str(card).startswith("HIERARCH ") and not remapped_keyword.startswith(
179-
"HIERARCH "
180-
):
181-
remapped_keyword = "HIERARCH " + remapped_keyword
182-
183-
card = Card(remapped_keyword, card.value, card.comment)
184-
185-
# Here we disable the use of blank cards, because the call above to
186-
# Header.append may have already deleted a blank card in the table
187-
# header, thanks to inheritance: Header.append calls 'del self[-1]'
188-
# to delete a blank card, which calls CompImageHeader.__deltitem__,
189-
# which deletes the blank card both in the image and the table headers!
190-
self._table_header.append(card=card, useblanks=False, bottom=bottom, end=end)
191-
192117
def insert(self, key, card, useblanks=True, after=False):
193118
if isinstance(key, int):
194119
# Determine condition to pass through to append
@@ -209,33 +134,14 @@ def insert(self, key, card, useblanks=True, after=False):
209134
elif not isinstance(card, Card):
210135
raise ValueError(
211136
"The value inserted into a Header must be either a keyword or "
212-
f"(keyword, value, [comment]) tuple; got: {card!r}"
137+
"(keyword, value, [comment]) tuple; got: {!r}".format(card)
213138
)
214139

215140
if self._is_reserved_keyword(card.keyword):
216141
return
217142

218-
# Now the tricky part is to determine where to insert in the table
219-
# header. If given a numerical index we need to map that to the
220-
# corresponding index in the table header. Although rare, there may be
221-
# cases where there is no mapping in which case we just try the same
222-
# index
223-
# NOTE: It is crucial that remapped_index in particular is figured out
224-
# before the image header is modified
225-
remapped_index = self._remap_index(key)
226-
remapped_keyword = self._remap_keyword(card.keyword)
227-
228143
super().insert(key, card, useblanks=useblanks, after=after)
229144

230-
card = Card(remapped_keyword, card.value, card.comment)
231-
232-
# Here we disable the use of blank cards, because the call above to
233-
# Header.insert may have already deleted a blank card in the table
234-
# header, thanks to inheritance: Header.insert calls 'del self[-1]'
235-
# to delete a blank card, which calls CompImageHeader.__delitem__,
236-
# which deletes the blank card both in the image and the table headers!
237-
self._table_header.insert(remapped_index, card, useblanks=False, after=after)
238-
239145
def _update(self, card):
240146
keyword = card[0]
241147

@@ -244,50 +150,12 @@ def _update(self, card):
244150

245151
super()._update(card)
246152

247-
if keyword in Card._commentary_keywords:
248-
# Otherwise this will result in a duplicate insertion
249-
return
250-
251-
remapped_keyword = self._remap_keyword(keyword)
252-
self._table_header._update((remapped_keyword,) + card[1:])
253-
254-
# Last piece needed (I think) for synchronizing with the real header
255-
# This one is tricky since _relativeinsert calls insert
256-
def _relativeinsert(self, card, before=None, after=None, replace=False):
257-
keyword = card[0]
258-
259-
if self._is_reserved_keyword(keyword):
260-
return
261-
262-
# Now we have to figure out how to remap 'before' and 'after'
263-
if before is None:
264-
if isinstance(after, int):
265-
remapped_after = self._remap_index(after)
266-
else:
267-
remapped_after = self._remap_keyword(after)
268-
remapped_before = None
269-
else:
270-
if isinstance(before, int):
271-
remapped_before = self._remap_index(before)
272-
else:
273-
remapped_before = self._remap_keyword(before)
274-
remapped_after = None
275-
276-
super()._relativeinsert(card, before=before, after=after, replace=replace)
277-
278-
remapped_keyword = self._remap_keyword(keyword)
279-
280-
card = Card(remapped_keyword, card[1], card[2])
281-
self._table_header._relativeinsert(
282-
card, before=remapped_before, after=remapped_after, replace=replace
283-
)
284-
285153
@classmethod
286154
def _is_reserved_keyword(cls, keyword, warn=True):
287155
msg = (
288-
f"Keyword {keyword!r} is reserved for use by the FITS Tiled Image "
156+
"Keyword {!r} is reserved for use by the FITS Tiled Image "
289157
"Convention and will not be stored in the header for the "
290-
"image being compressed."
158+
"image being compressed.".format(keyword)
291159
)
292160

293161
if keyword == "TFIELDS":
@@ -318,51 +186,6 @@ def _is_reserved_keyword(cls, keyword, warn=True):
318186

319187
return False
320188

321-
@classmethod
322-
def _remap_keyword(cls, keyword):
323-
# Given a keyword that one might set on an image, remap that keyword to
324-
# the name used for it in the COMPRESSED HDU header
325-
# This is mostly just a lookup in _keyword_remaps, but needs handling
326-
# for NAXISn keywords
327-
328-
is_naxisn = False
329-
if keyword[:5] == "NAXIS":
330-
with suppress(ValueError):
331-
index = int(keyword[5:])
332-
is_naxisn = index > 0
333-
334-
if is_naxisn:
335-
return f"ZNAXIS{index}"
336-
337-
# If the keyword does not need to be remapped then just return the
338-
# original keyword
339-
return cls._keyword_remaps.get(keyword, keyword)
340-
341-
def _remap_index(self, idx):
342-
# Given an integer index into this header, map that to the index in the
343-
# table header for the same card. If the card doesn't exist in the
344-
# table header (generally should *not* be the case) this will just
345-
# return the same index
346-
# This *does* also accept a keyword or (keyword, repeat) tuple and
347-
# obtains the associated numerical index with self._cardindex
348-
if not isinstance(idx, int):
349-
idx = self._cardindex(idx)
350-
351-
keyword, repeat = self._keyword_from_index(idx)
352-
remapped_insert_keyword = self._remap_keyword(keyword)
353-
354-
with suppress(IndexError, KeyError):
355-
idx = self._table_header._cardindex((remapped_insert_keyword, repeat))
356-
357-
return idx
358-
359-
def clear(self):
360-
"""
361-
Remove all cards from the header.
362-
"""
363-
self._table_header.clear()
364-
super().clear()
365-
366189

367190
def _bintable_header_to_image_header(bintable_header):
368191
# Start with a copy of the table header.

0 commit comments

Comments
 (0)