1 __all__ = [
"CardType",
"FitsChan",
"FitsKeyState"]
3 from .fitsChan
import CardType, FitsChan, FitsKeyState
6 def _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})")
36 def _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")
85 FitsChan.__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.
102 FitsChan.__iter__ = iter
106 """Return each 80-character header card until we run out of cards.
108 card = self.findFits(
"%f",
True)
114 FitsChan.__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)
124 FitsChan.__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)
148 FitsChan.__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")
221 FitsChan.__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)
315 FitsChan.__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}")
363 FitsChan.__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()
394 FitsChan.items = items