1__all__ = [
"CardType",
"FitsChan",
"FitsKeyState"]
3from .fitsChan
import CardType, FitsChan, FitsKeyState
6def _calc_card_pos(self, index):
7 """Convert a python index into a FitsChan position.
12 The FitsChan to index.
14 0-based index into header. If negative, counts from end.
19 Raised
if the index exceeds the size of the FitsChan. If the index
20 equals the size of the FitsChan (noting that
in 0-based indexing the
21 final card
is one less than the size) then this refers to the end of
27 index = nCards + index
28 elif abs(index) > nCards:
30 raise IndexError(f
"Index {index} exceeds size of FitsChan ({nCards})")
36def _get_current_card_value(self):
37 """Retrieve the value of the current card along with the keyword name.
42 The name of the current card.
44 The value in the correct Python type.
47 typeLut = {CardType.INT: self.getFitsI,
48 CardType.FLOAT: self.getFitsF,
49 CardType.STRING: self.getFitsS,
50 CardType.COMPLEXF: self.getFitsCF,
51 CardType.LOGICAL: self.getFitsL
55 ctype = self.getCardType()
58 name = self.getCardName()
65 if ctype == CardType.UNDEF:
67 elif ctype
in typeLut:
68 found = typeLut[ctype](
"")
72 raise RuntimeError(f
"Unexpectedly failed to find card '{name}'")
73 elif ctype == CardType.COMMENT:
74 value = self.getCardComm()
76 raise RuntimeError(f
"Type, {ctype} of FITS card '{name}' not supported")
85FitsChan.__len__ = length
89 """The FitsChan is its own iterator, incrementing the card position on
92 The position of the iterator is handled internally
in the FitsChan
and
93 is moved to the start of the FitsChan by this call.
94 Whilst iterating do
not change the internal card position.
96 The iterator will
return 80-character header cards.
102FitsChan.__iter__ = iter
106 """Return each 80-character header card until we run out of cards.
108 card = self.findFits("%f",
True)
114FitsChan.__next__ = next
118 """A FitsChan string representation is a FITS header with newlines
119 after each 80-character header card.
121 return "\n".join(c
for c
in self)
124FitsChan.__str__ = to_string
128 """Returns True if either the supplied name is present in the FitsChan
129 or the supplied integer
is acceptable to the FitsChan.
131 if isinstance(name, int):
133 if name >= 0
and name < self.nCard:
135 elif isinstance(name, str):
136 currentCard = self.getCard()
139 result = self.findFits(name,
False)
141 self.setCard(currentCard)
148FitsChan.__contains__ = contains
152 """Return a value associated with the supplied name.
156 name : `str` or `int`
157 If the FitsChan
is being accessed by integer index the returned value
158 will be the corresponding 80-character card. Index values are 0-based.
159 A negative index counts
from the end of the FitsChan.
160 If the FitsChan
is being accessed by string the returned value will
161 be the scalar value associated
with the first card that matches the
166 value : `str`, `int`, `float`, `bool`,
or `
None`
167 The complete 80-character header card
if an integer index
is supplied,
168 else the first matching value of the named header.
173 Raised
if an integer index
is provided
and the index
is out of range.
175 Raised
if a string
is provided
and that string
is not present
in
176 the FitsChan. Also raised
if the supplied name
is neither an integer
179 Raised
if there
is some problem accessing the value
in the FitsChan.
183 currentCard = self.getCard()
185 if isinstance(name, int):
187 newpos = _calc_card_pos(self, name)
190 result = self.findFits(
"%f",
False)
192 self.setCard(currentCard)
194 raise IndexError(f
"No FITS card at index {name}")
197 elif isinstance(name, str):
204 result = self.findFits(name,
False)
206 raise KeyError(f
"{name}'")
208 this_name, value = _get_current_card_value(self)
209 if this_name != name:
210 raise RuntimeError(f
"Internal inconsistency in get: {this_name} != {name}")
214 self.setCard(currentCard)
218 raise KeyError(f
"Supplied key, '{name}' of unsupported type")
221FitsChan.__getitem__ = getitem
229 name : `str` or `int`
230 If the name
is an integer index this corresponds to a position within
231 the FitsChan. Index values are 0-based. A negative index counts
232 from the end of the FitsChan. If the index matches the number of
233 cards (e.g. the
return value of `len()`) the new value will be
234 appended to the end of the FitsChan.
235 If the name
is an empty string
or `
None`, the value will be inserted
236 at the current card position
as a comment card.
237 If the name
is a string corresponding to a header card that
is already
238 present
in the FitsChan, the new value will overwrite the existing
239 value leaving the header name
and any comment unchanged.
240 Any other cards matching that name later
in the header will
241 be removed. If there
is no header
with that name, a new card will
242 be inserted at the end of the FitsChan.
243 value : `str`, `int`, `float`, `bool`, `
None`
244 The new value to be inserted. If an integer index
is given it must be
245 a complete FITS header card. The string will be padded to 80
251 Raised
if the supplied integer index
is out of range.
253 Raised
if the supplied name
is neither a string
or an integer.
255 Raised
if an integer index
is given but the supplied value
is not
259 if isinstance(name, int):
261 newpos = _calc_card_pos(self, name)
268 self.putFits(value,
True)
274 self.setFitsCM(value,
False)
277 if not isinstance(name, str):
278 raise KeyError(f
"Supplied key, '{name}' of unsupported type")
281 currentCard = self.getCard()
288 self.findFits(name,
False)
293 self.setFitsU(name, overwrite=
True)
294 elif isinstance(value, int):
295 self.setFitsI(name, value, overwrite=
True)
296 elif isinstance(value, float):
297 self.setFitsF(name, value, overwrite=
True)
298 elif isinstance(value, bool):
299 self.setFitsL(name, value, overwrite=
True)
302 self.setFitsS(name, str(value), overwrite=
True)
306 found = self.findFits(name,
False)
312 self.setCard(currentCard)
315FitsChan.__setitem__ = setitem
319 """Delete an item from the FitsChan either by index (0-based) or by name.
323 name : `str` or `int`
324 If the name
is an integer index the card at that position will be
325 removed. The index
is zero-based. A negative index counts
from the
327 If the name
is a string all cards matching that name will be removed.
332 Raised
if the supplied index
is out of range.
334 Raised
if the supplied name
is not found
in the FitsChan.
336 if isinstance(name, int):
338 newpos = _calc_card_pos(self, name)
339 if newpos <= 0
or newpos > self.nCard:
341 raise IndexError(f
"No FITS card at index {name}")
346 if not isinstance(name, str):
347 raise KeyError(f
"Supplied key, '{name}' of unsupported type")
353 found = self.findFits(name,
False)
360 raise KeyError(f
"No FITS card named {name}")
363FitsChan.__delitem__ = delitem
367 """Iterate over each card, returning the keyword and value in a tuple.
372 The key associated with the card. Can be an empty string
for some
373 comment styles. The same key name can be returned multiple times
374 and be associated
with different values.
375 value : `str`, `int`, `bool`, `float`
380 The position of the iterator
is internal to the FitsChan. Do
not
381 change the card position when iterating.
385 thisCard = self.getCard()
387 while thisCard <= nCards:
388 name, value = _get_current_card_value(self)
390 self.setCard(thisCard + 1)
391 thisCard = self.getCard()
394FitsChan.items = items
def setitem(self, name, value)