1 """
2 A grammar to parse from primary FITS headers.
3
4 This grammar will return exactly one row per source.
5 """
6
7
8
9
10
11
12
13 import gzip
14 import re
15
16 from gavo import base
17 from gavo.grammars.common import Grammar, RowIterator, MapKeys
18 from gavo.utils import fitstools
19 from gavo.utils import pyfits
20
21
22
25 if self.grammar.qnd:
26 return self._parseFast()
27 else:
28 return self._parseSlow()
29
31 """tries to make *anything* from a card pyfits doesn't want to parse.
32
33 In reality, I'm just trying to cope with oversized keywords.
34 """
35 mat = re.match(r"([^\s=]*)\s*=\s*([^/]+)", card.image)
36 if mat:
37 res[mat.group(1)] = mat.group(2).strip()
38 else:
39 pass
40
42 res = {}
43 for card in header.cards:
44 try:
45 res[card.keyword.replace("-", "_")] = card.value
46 except (ValueError, pyfits.VerifyError):
47 self._hackBotchedCard(card, res)
48
49 res["header_"] = header
50
51 if self.grammar.hdusField:
52 res[self.grammar.hdusField] = fitstools.openFits(self.sourceToken)
53 return self.grammar.mapKeys.doMap(res)
54
65
75
77 return self.sourceToken
78
79
81 r"""A grammar that returns FITS-headers as dictionaries.
82
83 This is the grammar you want when one FITS file corresponds to one
84 row in the destination table.
85
86 The keywords of the grammar record are the cards in the primary
87 header (or some other hdu using the same-named attribute). "-" in
88 keywords is replaced with an underscore for easier @-referencing.
89 You can use a mapKeys element to effect further name cosmetics.
90
91 This grammar should handle compressed FITS images transparently if
92 set qnd="False". This means that you will essentially get the headers
93 from the second extension for those even if you left hdu="0".
94
95 The original header is preserved as the value of the header\_ key. This
96 is mainly intended for use WCS use, as in ``wcs.WCS(@header_)``.
97
98 If you have more complex structures in your FITS files, you can get access
99 to the pyfits HDU using the hdusField attribute. With
100 ``hdusField="_H"``, you could say things like ``@_H[1].data[10][0]``
101 to get the first data item in the tenth row in the second HDU.
102 """
103 name_ = "fitsProdGrammar"
104
105 _qnd = base.BooleanAttribute("qnd", default=True, description=
106 "Use a hack to read the FITS header more quickly. This only"
107 " works for the primary HDU", copyable=True)
108 _hduIndex = base.IntAttribute("hdu", default=0,
109 description="Take the header from this HDU. You must say qnd='False'"
110 " for this to take effect.", copyable=True)
111 _mapKeys = base.StructAttribute("mapKeys", childFactory=MapKeys,
112 default=None, copyable=True, description="Prescription for how to"
113 " map header keys to grammar dictionary keys")
114 _hdusAttr = base.UnicodeAttribute("hdusField", default=None,
115 description="If set, the complete pyfits HDU list for the FITS"
116 " file is returned in this grammar field.", copyable=True)
117 _maxHeaderBlocks = base.IntAttribute("maxHeaderBlocks",
118 default=40, copyable=True, description="Stop looking for"
119 " FITS END cards and raise an error after this many blocks."
120 " You may need to raise this for people dumping obscene amounts"
121 " of data or history into headers.")
122
123 rowIterator = FITSProdIterator
124
129