@@ -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
367190def _bintable_header_to_image_header (bintable_header ):
368191 # Start with a copy of the table header.
0 commit comments