View Javadoc
1   package nom.tam.fits.header;
2   
3   import nom.tam.fits.AsciiTable;
4   import nom.tam.fits.BinaryTable;
5   import nom.tam.fits.ImageData;
6   import nom.tam.fits.RandomGroupsData;
7   import nom.tam.fits.TableData;
8   import nom.tam.fits.UndefinedData;
9   
10  /*
11   * #%L
12   * nom.tam FITS library
13   * %%
14   * Copyright (C) 1996 - 2024 nom-tam-fits
15   * %%
16   * This is free and unencumbered software released into the public domain.
17   *
18   * Anyone is free to copy, modify, publish, use, compile, sell, or
19   * distribute this software, either in source code form or as a compiled
20   * binary, for any purpose, commercial or non-commercial, and by any
21   * means.
22   *
23   * In jurisdictions that recognize copyright laws, the author or authors
24   * of this software dedicate any and all copyright interest in the
25   * software to the public domain. We make this dedication for the benefit
26   * of the public at large and to the detriment of our heirs and
27   * successors. We intend this dedication to be an overt act of
28   * relinquishment in perpetuity of all present and future rights to this
29   * software under copyright law.
30   *
31   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
34   * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
35   * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
36   * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
37   * OTHER DEALINGS IN THE SOFTWARE.
38   * #L%
39   */
40  
41  /**
42   * <p>
43   * This data dictionary lists the 53 keywords currently defined in the FITS Standard.
44   * </p>
45   * <p>
46   * See <a href=
47   * "http://heasarc.gsfc.nasa.gov/docs/fcg/standard_dict.html">http://heasarc.gsfc.nasa.gov/docs/fcg/standard_dict.html</a>
48   * </p>
49   *
50   * @author Richard van Nieuwenhoven
51   */
52  @SuppressWarnings("deprecation")
53  public enum Standard implements IFitsHeader {
54      /**
55       * The value field shall contain a character string identifying who compiled the information in the data associated
56       * with the key. This keyword is appropriate when the data originate in a published paper or are compiled from many
57       * sources.
58       */
59      AUTHOR(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "author name(s)"),
60      /**
61       * The value field shall contain an integer. The absolute value is used in computing the sizes of data structures.
62       * It shall specify the number of bits that represent a data value. RANGE: -64,-32,8,16,32
63       * 
64       * @see Bitpix
65       */
66      BITPIX(SOURCE.MANDATORY, HDU.ANY, VALUE.INTEGER, "bits per data element", //
67              replaceable("header:bitpix", Object.class) //
68      ),
69  
70      /**
71       * This keyword shall be used only in primary array headers or IMAGE extension headers with positive values of
72       * BITPIX (i.e., in arrays with integer data). Columns 1-8 contain the string, `BLANK ' (ASCII blanks in columns
73       * 6-8). The value field shall contain an integer that specifies the representation of array values whose physical
74       * values are undefined.
75       */
76      BLANK(SOURCE.RESERVED, HDU.IMAGE, VALUE.INTEGER, "value used for undefined array elements"),
77  
78      /**
79       * Columns 1-8 contain ASCII blanks. This keyword has no associated value. Columns 9-80 may contain any ASCII text.
80       * Any number of card images with blank keyword fields may appear in a key.
81       */
82      BLANKS("", SOURCE.RESERVED, HDU.ANY, VALUE.NONE, null),
83  
84      /**
85       * This keyword may be used only in the primary key. It shall appear within the first 36 card images of the FITS
86       * file. (Note: This keyword thus cannot appear if NAXIS is greater than 31, or if NAXIS is greater than 30 and the
87       * EXTEND keyword is present.) Its presence with the required logical value of T advises that the physical block
88       * size of the FITS file on which it appears may be an integral multiple of the logical record length, and not
89       * necessarily equal to it. Physical block size and logical record length may be equal even if this keyword is
90       * present or unequal if it is absent. It is reserved primarily to prevent its use with other meanings. Since the
91       * issuance of version 1 of the standard, the BLOCKED keyword has been deprecated.
92       *
93       * @deprecated no blocksize other that 2880 may be used.
94       */
95      @Deprecated
96      BLOCKED(SOURCE.RESERVED, HDU.PRIMARY, VALUE.LOGICAL, "Non-standard FITS block size"),
97  
98      /**
99       * This keyword shall be used, along with the BZERO keyword, when the array pixel values are not the true physical
100      * values, to transform the primary data array values to the true physical values they represent, using the
101      * equation: physical_value = BZERO + BSCALE * array_value. The value field shall contain a floating point number
102      * representing the coefficient of the linear term in the scaling equation, the ratio of physical value to array
103      * value at zero offset. The default value for this keyword is 1.0.
104      */
105     BSCALE(SOURCE.RESERVED, HDU.IMAGE, VALUE.REAL, "data quantization scaling"),
106 
107     /**
108      * The value field shall contain a character string, describing the physical units in which the quantities in the
109      * array, after application of BSCALE and BZERO, are expressed. The units of all FITS key keyword values, with the
110      * exception of measurements of angles, should conform with the recommendations in the IAU Style Manual. For angular
111      * measurements given as floating point values and specified with reserved keywords, degrees are the recommended
112      * units (with the units, if specified, given as 'deg').
113      */
114     BUNIT(SOURCE.RESERVED, HDU.IMAGE, VALUE.STRING, "data physical unit"),
115 
116     /**
117      * This keyword shall be used, along with the BSCALE keyword, when the array pixel values are not the true physical
118      * values, to transform the primary data array values to the true values using the equation: physical_value = BZERO
119      * + BSCALE * array_value. The value field shall contain a floating point number representing the physical value
120      * corresponding to an array value of zero. The default value for this keyword is 0.0.
121      */
122     BZERO(SOURCE.RESERVED, HDU.IMAGE, VALUE.REAL, "data quantization offset"),
123 
124     /**
125      * The value field shall contain a floating point number giving the partial derivative of the coordinate specified
126      * by the CTYPEn keywords with respect to the pixel index, evaluated at the reference point CRPIXn, in units of the
127      * coordinate specified by the CTYPEn keyword. These units must follow the prescriptions of section 5.3 of the FITS
128      * Standard.
129      *
130      * @see WCS#CDELTna
131      */
132     CDELTn(SOURCE.RESERVED, HDU.IMAGE, VALUE.REAL, "coordinate spacing along axis"),
133 
134     /**
135      * This keyword shall have no associated value; columns 9-80 may contain any ASCII text. Any number of COMMENT card
136      * images may appear in a key.
137      */
138     COMMENT(SOURCE.RESERVED, HDU.ANY, VALUE.NONE, null),
139 
140     /**
141      * The CONTINUE keyword, when followed by spaces in columns 9 and 10 of the card image and a character string
142      * enclosed in single quotes starting in column 11 or higher, indicates that the quoted string should be treated as
143      * a continuation of the character string value in the previous key keyword. To conform to this convention, the
144      * character string value on the previous keyword must end with the ampersand character ('&amp;'), but the ampersand
145      * is not part of the value string and should be deleted before concatenating the strings together. The character
146      * string value may be continued on any number of consecutive CONTINUE keywords, thus effectively allowing
147      * arbitrarily long strings to be written as keyword values.
148      */
149     CONTINUE(SOURCE.RESERVED, HDU.ANY, VALUE.NONE, null),
150 
151     /**
152      * This keyword is used to indicate a rotation from a standard coordinate system described by the CTYPEn to a
153      * different coordinate system in which the values in the array are actually expressed. Rules for such rotations are
154      * not further specified in the Standard; the rotation should be explained in comments. The value field shall
155      * contain a floating point number giving the rotation angle in degrees between axis n and the direction implied by
156      * the coordinate system defined by CTYPEn. In unit degrees.
157      */
158     CROTAn(SOURCE.RESERVED, HDU.IMAGE, VALUE.REAL, "[deg] coordinate axis rotation angle"),
159 
160     /**
161      * The value field shall contain a floating point number, identifying the location of a reference point along axis
162      * n, in units of the axis index. This value is based upon a counter that runs from 1 to NAXISn with an increment of
163      * 1 per pixel. The reference point value need not be that for the center of a pixel nor lie within the actual data
164      * array. Use comments to indicate the location of the index point relative to the pixel.
165      * 
166      * @see WCS#CRPIXna
167      */
168     CRPIXn(SOURCE.RESERVED, HDU.IMAGE, VALUE.REAL, "coordinate axis reference pixel"),
169 
170     /**
171      * The value field shall contain a floating point number, giving the value of the coordinate specified by the CTYPEn
172      * keyword at the reference point CRPIXn. Units must follow the prescriptions of section 5.3 of the FITS Standard.
173      *
174      * @see WCS#CRVALna
175      */
176     CRVALn(SOURCE.RESERVED, HDU.IMAGE, VALUE.REAL, "coordinate axis value at reference pixel"),
177 
178     /**
179      * The value field shall contain a character string, giving the name of the coordinate represented by axis n.
180      *
181      * @see WCS#CTYPEna
182      */
183     CTYPEn(SOURCE.RESERVED, HDU.IMAGE, VALUE.STRING, "coordinate axis type / name"),
184 
185     /**
186      * The value field shall always contain a floating point number, regardless of the value of BITPIX. This number
187      * shall give the maximum valid physical value represented by the array, exclusive of any special values.
188      */
189     DATAMAX(SOURCE.RESERVED, HDU.IMAGE, VALUE.REAL, "maximum data value"),
190 
191     /**
192      * The value field shall always contain a floating point number, regardless of the value of BITPIX. This number
193      * shall give the minimum valid physical value represented by the array, exclusive of any special values.
194      */
195     DATAMIN(SOURCE.RESERVED, HDU.IMAGE, VALUE.REAL, "minimum data value"),
196 
197     /**
198      * The date on which the HDU was created, in the format specified in the FITS Standard. The old date format was
199      * 'yy/mm/dd' and may be used only for dates from 1900 through 1999. the new Y2K compliant date format is
200      * 'yyyy-mm-dd' or 'yyyy-mm-ddTHH:MM:SS[.sss]'.
201      * 
202      * @see DateTime#DATE
203      */
204     DATE(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "date of file creation"),
205 
206     /**
207      * The date of the observation, in the format specified in the FITS Standard. The old date format was 'yy/mm/dd' and
208      * may be used only for dates from 1900 through 1999. The new Y2K compliant date format is 'yyyy-mm-dd' or
209      * 'yyyy-mm-ddTHH:MM:SS[.sss]'.
210      * 
211      * @see DateTime#DATE_OBS
212      */
213     DATE_OBS("DATE-OBS", SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "date of the observation"),
214 
215     /**
216      * This keyword has no associated value. Columns 9-80 shall be filled with ASCII blanks.
217      */
218     END(SOURCE.MANDATORY, HDU.ANY, VALUE.NONE, null),
219 
220     /**
221      * The value field shall contain a floating point number giving the equinox in years for the celestial coordinate
222      * system in which positions are expressed. Starting with Version 1, the Standard has deprecated the use of the
223      * EPOCH keyword and thus it shall not be used in FITS files created after the adoption of the standard; rather, the
224      * EQUINOX keyword shall be used.
225      *
226      * @deprecated Deprecated by the FITS standard in favor of {@link #EQUINOX}.
227      */
228     EPOCH(SOURCE.RESERVED, HDU.ANY, VALUE.REAL, "[yr] equinox of celestial coordinate system"),
229 
230     /**
231      * The value field shall contain a floating point number giving the equinox in years for the celestial coordinate
232      * system in which positions are expressed. This version of the keyword does not support alternative coordinate
233      * systems.
234      * 
235      * @see WCS#EQUINOXa
236      */
237     EQUINOX(SOURCE.RESERVED, HDU.ANY, VALUE.REAL, "[yr] equinox of celestial coordinate system"),
238 
239     /**
240      * If the FITS file may contain extensions, a card image with the keyword EXTEND and the value field containing the
241      * logical value T must appear in the primary key immediately after the last NAXISn card image, or, if NAXIS=0, the
242      * NAXIS card image. The presence of this keyword with the value T in the primary key does not require that
243      * extensions be present.
244      */
245     EXTEND(SOURCE.INTEGRAL, HDU.PRIMARY, VALUE.LOGICAL, "allow extensions"),
246 
247     /**
248      * The value field shall contain an integer, specifying the level in a hierarchy of extension levels of the
249      * extension key containing it. The value shall be 1 for the highest level; levels with a higher value of this
250      * keyword shall be subordinate to levels with a lower value. If the EXTLEVEL keyword is absent, the file should be
251      * treated as if the value were 1. This keyword is used to describe an extension and should not appear in the
252      * primary key.RANGE: [1:] DEFAULT: 1
253      */
254     EXTLEVEL(SOURCE.RESERVED, HDU.ANY, VALUE.INTEGER, "hierarchical level of the extension"),
255 
256     /**
257      * The value field shall contain a character string, to be used to distinguish among different extensions of the
258      * same type, i.e., with the same value of XTENSION, in a FITS file. This keyword is used to describe an extension
259      * and but may appear in the primary header also.
260      */
261     EXTNAME(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "HDU name"),
262 
263     /**
264      * The value field shall contain an integer, to be used to distinguish among different extensions in a FITS file
265      * with the same type and name, i.e., the same values for XTENSION and EXTNAME. The values need not start with 1 for
266      * the first extension with a particular value of EXTNAME and need not be in sequence for subsequent values. If the
267      * EXTVER keyword is absent, the file should be treated as if the value were 1. This keyword is used to describe an
268      * extension and should not appear in the primary key.RANGE: [1:] DEFAULT: 1
269      */
270     EXTVER(SOURCE.RESERVED, HDU.ANY, VALUE.INTEGER, "HDU version"),
271 
272     /**
273      * The value field shall contain an integer that shall be used in any way appropriate to define the data structure,
274      * consistent with Eq. 5.2 in the FITS Standard. This keyword originated for use in FITS Random Groups where it
275      * specifies the number of random groups present. In most other cases this keyword will have the value 1.
276      */
277     GCOUNT(SOURCE.MANDATORY, HDU.ANY, VALUE.INTEGER, "group count",
278             replaceable("randomgroupsdata:groups", RandomGroupsData.class), //
279             replaceable("undefineddata:groups", UndefinedData.class), //
280             replaceable("header:groups", RandomGroupsData.class) //
281     ),
282 
283     /**
284      * The value field shall contain the logical constant T. The value T associated with this keyword implies that
285      * random groups records are present.
286      */
287     GROUPS(SOURCE.MANDATORY, HDU.GROUPS, VALUE.LOGICAL, "random groups data", //
288             replaceable("randomgroupsdata:groups", RandomGroupsData.class) //
289     ),
290 
291     /**
292      * This keyword shall have no associated value; columns 9-80 may contain any ASCII text. The text should contain a
293      * history of steps and procedures associated with the processing of the associated data. Any number of HISTORY card
294      * images may appear in a key.
295      */
296     HISTORY(SOURCE.RESERVED, HDU.ANY, VALUE.NONE, "processing history of the data"),
297 
298     /**
299      * The value field shall contain a character string identifying the instrument used to acquire the data associated
300      * with the key.
301      */
302     INSTRUME(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "name of instrument"),
303 
304     /**
305      * The value field shall contain a non-negative integer no greater than 999, representing the number of axes in the
306      * associated data array. A value of zero signifies that no data follow the key in the HDU. In the context of FITS
307      * 'TABLE' or 'BINTABLE' extensions, the value of NAXIS is always 2.RANGE: [0:999]
308      */
309     NAXIS(SOURCE.MANDATORY, HDU.ANY, VALUE.INTEGER, "dimensionality of data"),
310 
311     /**
312      * The value field of this indexed keyword shall contain a non-negative integer, representing the number of elements
313      * along axis n of a data array. The NAXISn must be present for all values n = 1,...,NAXIS, and for no other values
314      * of n. A value of zero for any of the NAXISn signifies that no data follow the key in the HDU. If NAXIS is equal
315      * to 0, there should not be any NAXISn keywords.RANGE: [0:]
316      */
317     NAXISn(SOURCE.MANDATORY, HDU.ANY, VALUE.INTEGER, "n'th data dimension", //
318             replaceable("tablehdu:naxis1", TableData.class, "Size of table row in bytes"), //
319             replaceable("tablehdu:naxis2", TableData.class, "Number of table rows"),
320             replaceable("header:naxis2", Object.class)),
321 
322     /**
323      * The value field shall contain a character string giving a name for the object observed.
324      */
325     OBJECT(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "name of observed object"),
326 
327     /**
328      * The value field shall contain a character string identifying who acquired the data associated with the key.
329      */
330     OBSERVER(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "observer(s) who acquired the data"),
331 
332     /**
333      * The value field shall contain a character string identifying the organization or institution responsible for
334      * creating the FITS file.
335      */
336     ORIGIN(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "organization responsible for the data"),
337 
338     /**
339      * The value field shall contain an integer that shall be used in any way appropriate to define the data structure,
340      * consistent with Eq. 5.2 in the FITS Standard. This keyword was originated for use with FITS Random Groups and
341      * represented the number of parameters preceding each group. It has since been used in 'BINTABLE' extensions to
342      * represent the size of the data heap following the main data table. In most other cases its value will be zero.
343      */
344     PCOUNT(SOURCE.MANDATORY, HDU.ANY, VALUE.INTEGER, "associated parameter count", //
345             replaceable("binarytable:pcount", TableData.class, "heap size in bytes"),
346             replaceable("randomgroups:pcount", RandomGroupsData.class, "parameter values per group"),
347             replaceable("undefineddata:pcount", UndefinedData.class), replaceable("header:pcount", Object.class)),
348 
349     /**
350      * This keyword is reserved for use within the FITS Random Groups structure. This keyword shall be used, along with
351      * the PZEROn keyword, when the nth FITS group parameter value is not the true physical value, to transform the
352      * group parameter value to the true physical values it represents, using the equation, physical_value = PZEROn +
353      * PSCALn * group_parameter_value. The value field shall contain a floating point number representing the
354      * coefficient of the linear term, the scaling factor between true values and group parameter values at zero offset.
355      * The default value for this keyword is 1.0.
356      */
357     PSCALn(SOURCE.INTEGRAL, HDU.GROUPS, VALUE.REAL, "parameter quantization scaling"),
358 
359     /**
360      * This keyword is reserved for use within the FITS Random Groups structure. The value field shall contain a
361      * character string giving the name of parameter n. If the PTYPEn keywords for more than one value of n have the
362      * same associated name in the value field, then the data value for the parameter of that name is to be obtained by
363      * adding the derived data values of the corresponding parameters. This rule provides a mechanism by which a random
364      * parameter may have more precision than the accompanying data array elements; for example, by summing two 16-bit
365      * values with the first scaled relative to the other such that the sum forms a number of up to 32-bit precision.
366      */
367     PTYPEn(SOURCE.INTEGRAL, HDU.GROUPS, VALUE.STRING, "name of random groups parameter"),
368 
369     /**
370      * This keyword is reserved for use within the FITS Random Groups structure. This keyword shall be used, along with
371      * the PSCALn keyword, when the nth FITS group parameter value is not the true physical value, to transform the
372      * group parameter value to the physical value. The value field shall contain a floating point number, representing
373      * the true value corresponding to a group parameter value of zero. The default value for this keyword is 0.0. The
374      * transformation equation is as follows: physical_value = PZEROn + PSCALn * group_parameter_value.DEFAULT: 0.0
375      */
376     PZEROn(SOURCE.INTEGRAL, HDU.GROUPS, VALUE.REAL, "parameter quantization offset"),
377 
378     /**
379      * Coordinate reference frame of major/minor axes.If absent the default value is 'FK5'. This version of the keyword
380      * does not support alternative coordinate systems.
381      * 
382      * @see WCS#RADESYSa
383      */
384     RADESYS(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "celestial coordinate reference frame"),
385 
386     /**
387      * Coordinate reference frame of major/minor axes (generic).
388      *
389      * @deprecated Deprecated in the current FITS satndard, use {@link #RADESYS} instead.
390      */
391     RADECSYS(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "celestial coordinate reference frame"),
392 
393     /**
394      * [Hz] Rest frequency of observed spectral line.
395      * 
396      * @since 1.19
397      * 
398      * @see   WCS#RESTFRQa
399      */
400     RESTFRQ(SOURCE.RESERVED, HDU.IMAGE, VALUE.REAL, "[Hz] line rest frequency"),
401 
402     /**
403      * [Hz] Rest frequeny of observed spectral line (generic).
404      *
405      * @deprecated Deprecated in the current FITS standard, use {@link #RESTFRQ} instead.
406      */
407     RESTFREQ(SOURCE.RESERVED, HDU.ANY, VALUE.REAL, "[Hz] observed line rest frequency"),
408 
409     /**
410      * The value field shall contain a character string citing a reference where the data associated with the key are
411      * published.
412      */
413     REFERENC(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "bibliographic reference"),
414 
415     /**
416      * The SIMPLE keyword is required to be the first keyword in the primary key of all FITS files. The value field
417      * shall contain a logical constant with the value T if the file conforms to the standard. This keyword is mandatory
418      * for the primary key and is not permitted in extension headers. A value of F signifies that the file does not
419      * conform to this standard.
420      */
421     SIMPLE(SOURCE.MANDATORY, HDU.PRIMARY, VALUE.LOGICAL, "primary HDU", //
422             replaceable("header:simple", Object.class, "Java FITS: " + new java.util.Date()) //
423     ),
424 
425     /**
426      * The value field of this indexed keyword shall contain an integer specifying the column in which field n starts in
427      * an ASCII TABLE extension. The first column of a row is numbered 1.RANGE: [1:]
428      */
429     TBCOLn(SOURCE.MANDATORY, HDU.ASCII_TABLE, VALUE.INTEGER, "column byte offset", //
430             replaceable("asciitable:tbcolN", AsciiTable.class) //
431     ),
432 
433     /**
434      * The value field of this indexed keyword shall contain a character string describing how to interpret the contents
435      * of field n as a multidimensional array, providing the number of dimensions and the length along each axis. The
436      * form of the value is not further specified by the Standard. A proposed convention is described in Appendix B.2 of
437      * the FITS Standard in which the value string has the format '(l,m,n...)' where l, m, n,... are the dimensions of
438      * the array.
439      */
440     TDIMn(SOURCE.RESERVED, HDU.BINTABLE, VALUE.STRING, "dimensionality of column array elements", //
441             replaceable("binarytable:tdimN", BinaryTable.class) //
442     ),
443 
444     /**
445      * The value field of this indexed keyword shall contain a character string describing the format recommended for
446      * the display of the contents of field n. If the table value has been scaled, the physical value shall be
447      * displayed. All elements in a field shall be displayed with a single, repeated format. For purposes of display,
448      * each byte of bit (type X) and byte (type B) arrays is treated as an unsigned integer. Arrays of type A may be
449      * terminated with a zero byte. Only the format codes in Table 8.6, discussed in section 8.3.4 of the FITS Standard,
450      * are permitted for encoding. The format codes must be specified in upper case. If the Bw.m, Ow.m, and Zw.m formats
451      * are not readily available to the reader, the Iw.m display format may be used instead, and if the ENw.d and ESw.d
452      * formats are not available, Ew.d may be used. The meaning of this keyword is not defined for fields of type P in
453      * the Standard but may be defined in conventions using such fields.
454      */
455     TDISPn(SOURCE.RESERVED, HDU.TABLE, VALUE.STRING, "column display format"),
456 
457     /**
458      * The value field shall contain a character string identifying the telescope used to acquire the data associated
459      * with the key.
460      */
461     TELESCOP(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "name of telescope / observatory"),
462 
463     /**
464      * The value field shall contain a non-negative integer representing the number of fields in each row of a 'TABLE'
465      * or 'BINTABLE' extension. The maximum permissible value is 999. RANGE: [0:999]
466      */
467     TFIELDS(SOURCE.MANDATORY, HDU.TABLE, VALUE.INTEGER, "number of columns in the table"),
468 
469     /**
470      * The value field of this indexed keyword shall contain a character string describing the format in which field n
471      * is encoded in a 'TABLE' or 'BINTABLE' extension.
472      */
473     TFORMn(SOURCE.MANDATORY, HDU.TABLE, VALUE.STRING, "column data format", //
474             replaceable("asciitable:tformN", AsciiTable.class), //
475             replaceable("binarytable:tformN", BinaryTable.class) //
476     ),
477 
478     /**
479      * The value field of this keyword shall contain an integer providing the separation, in bytes, between the start of
480      * the main data table and the start of a supplemental data area called the heap. The default value shall be the
481      * product of the values of NAXIS1 and NAXIS2. This keyword shall not be used if the value of PCOUNT is zero. A
482      * proposed application of this keyword is presented in Appendix B.1 of the FITS Standard.
483      */
484     THEAP(SOURCE.INTEGRAL, HDU.BINTABLE, VALUE.INTEGER, "heap byte offset", //
485             replaceable("binarytable:theap", BinaryTable.class) //
486     ),
487 
488     /**
489      * In ASCII 'TABLE' extensions, the value field for this indexed keyword shall contain the character string that
490      * represents an undefined value for field n. The string is implicitly blank filled to the width of the field. In
491      * binary 'BINTABLE' table extensions, the value field for this indexed keyword shall contain the integer that
492      * represents an undefined value for field n of data type B, I, or J. The keyword may not be used in 'BINTABLE'
493      * extensions if field n is of any other data type.
494      */
495     TNULLn(SOURCE.INTEGRAL, HDU.TABLE, VALUE.ANY, "column value for undefined elements"),
496 
497     /**
498      * This indexed keyword shall be used, along with the TZEROn keyword, when the quantity in field n does not
499      * represent a true physical quantity. The value field shall contain a floating point number representing the
500      * coefficient of the linear term in the equation, physical_value = TZEROn + TSCALn * field_value, which must be
501      * used to compute the true physical value of the field, or, in the case of the complex data types C and M, of the
502      * real part of the field with the imaginary part of the scaling factor set to zero. The default value for this
503      * keyword is 1.0. This keyword may not be used if the format of field n is A, L, or X.DEFAULT: 1.0
504      */
505     TSCALn(SOURCE.RESERVED, HDU.TABLE, VALUE.REAL, "column quantization scaling"),
506 
507     /**
508      * The value field for this indexed keyword shall contain a character string, giving the name of field n. It is
509      * recommended that only letters, digits, and underscore (hexadecimal code 5F, ('_') be used in the name. String
510      * comparisons with the values of TTYPEn keywords should not be case sensitive. The use of identical names for
511      * different fields should be avoided.
512      */
513     TTYPEn(SOURCE.RESERVED, HDU.TABLE, VALUE.STRING, "column name"),
514 
515     /**
516      * The value field shall contain a character string describing the physical units in which the quantity in field n,
517      * after any application of TSCALn and TZEROn, is expressed. The units of all FITS key keyword values, with the
518      * exception of measurements of angles, should conform with the recommendations in the IAU Style Manual. For angular
519      * measurements given as floating point values and specified with reserved keywords, degrees are the recommended
520      * units (with the units, if specified, given as 'deg').
521      */
522     TUNITn(SOURCE.RESERVED, HDU.TABLE, VALUE.STRING, "column physical unit"),
523 
524     /**
525      * This indexed keyword shall be used, along with the TSCALn keyword, when the quantity in field n does not
526      * represent a true physical quantity. The value field shall contain a floating point number representing the true
527      * physical value corresponding to a value of zero in field n of the FITS file, or, in the case of the complex data
528      * types C and M, in the real part of the field, with the imaginary part set to zero. The default value for this
529      * keyword is 0.0. This keyword may not be used if the format of field n is A, L, or X.DEFAULT: 0.0
530      */
531     TZEROn(SOURCE.RESERVED, HDU.TABLE, VALUE.REAL, "column quantization offset"),
532 
533     /**
534      * The value field of this indexed keyword shall contain a floating point number specifying the maximum valid
535      * physical value represented in column n of the table, exclusive of any special values. This keyword may only be
536      * used in 'TABLE' or 'BINTABLE' extensions and is analogous to the DATAMAX keyword used for FITS images.
537      * 
538      * @since 1.19
539      */
540     TDMAXn(SOURCE.RESERVED, HDU.TABLE, VALUE.REAL, "maximum value in the column"),
541 
542     /**
543      * The value field of this indexed keyword shall contain a floating point number specifying the minimum valid
544      * physical value represented in column n of the table, exclusive of any special values. This keyword may only be
545      * used in 'TABLE' or 'BINTABLE' extensions and is analogous to the DATAMIN keyword used for FITS images.
546      * 
547      * @since 1.19
548      */
549     TDMINn(SOURCE.RESERVED, HDU.TABLE, VALUE.REAL, "minimum value in the column"),
550 
551     /**
552      * The value field of this indexed keyword shall contain a floating point number specifying the upper bound of the
553      * legal range of physical values that may be represented in column n of the table. The column may contain values
554      * that are greater than this legal maximum value but the interpretation of such values is not defined here. The
555      * value of this keyword is typically used as the maxinum value when constructing a histogram of the values in the
556      * column. This keyword may only be used in 'TABLE' or 'BINTABLE' extensions.
557      * 
558      * @since 1.19
559      */
560     TLMAXn(SOURCE.RESERVED, HDU.TABLE, VALUE.REAL, "maximum legal value in the column"),
561 
562     /**
563      * The value field of this indexed keyword shall contain a floating point number specifying the lower bound of the
564      * legal range of physical values that may be represented in column n of the table. The column may contain values
565      * that are less than this legal minimum value but the interpretation of such values is not defined here. The value
566      * of this keyword is typically used as the mininum value when constructing a histogram of the values in the column.
567      * This keyword may only be used in 'TABLE' or 'BINTABLE' extensions.
568      * 
569      * @since 1.19
570      */
571     TLMINn(SOURCE.RESERVED, HDU.TABLE, VALUE.REAL, "minimum legal value in the column"),
572 
573     /**
574      * The value field shall contain a character string giving the name of the extension type. This keyword is mandatory
575      * for an extension key and must not appear in the primary key. For an extension that is not a standard extension,
576      * the type name must not be the same as that of a standard extension.
577      */
578     XTENSION(SOURCE.MANDATORY, HDU.EXTENSION, VALUE.STRING, "HDU extension type",
579             replaceable("imagedata:xtension", ImageData.class, "image HDU"), //
580             replaceable("binarytable:xtension", BinaryTable.class, "binary table HDU"), //
581             replaceable("asciitable:xtension", AsciiTable.class, "ASCII table HDU"), //
582             replaceable("undefineddata:xtension", UndefinedData.class), //
583             replaceable("header:xtension", Object.class) //
584     ),
585 
586     /**
587      * If set to <code>true</code>, it indicates that the HDU should inherit all non-confliucting keywords from the
588      * primary HDU.
589      * 
590      * @since 1.19
591      */
592     INHERIT(SOURCE.RESERVED, HDU.EXTENSION, VALUE.LOGICAL, "inherit primary header entries");
593 
594     private static final ThreadLocal<Class<?>> COMMENT_CONTEXT = new ThreadLocal<>();
595 
596     /**
597      * A shorthand for {@link #NAXISn}<code>.n(1)</code>, that is the regular dimension along the first, fastest FITS
598      * array index (this is the same as the last dimension of Java arrays).
599      */
600     public static final IFitsHeader NAXIS1 = NAXISn.n(1);
601 
602     /**
603      * A shorthand for {@link #NAXISn}<code>.n(2)</code>, that is the regular dimension along the second fastest FITS
604      * array index (this is the same as the one before the last dimension of Java arrays).
605      */
606     public static final IFitsHeader NAXIS2 = NAXISn.n(2);
607 
608     /**
609      * The value of the XTENSION keword in case of a binary table.
610      */
611     public static final String XTENSION_ASCIITABLE = "TABLE";
612 
613     /**
614      * The value of the XTENSION keword in case of a binary table.
615      */
616     public static final String XTENSION_BINTABLE = "BINTABLE";
617 
618     /**
619      * The value of the XTENSION keword in case of an image.
620      */
621     public static final String XTENSION_IMAGE = "IMAGE";
622 
623     private final StandardCommentReplacement[] commentReplacements;
624 
625     private final FitsKey key;
626 
627     Standard(SOURCE status, HDU hdu, VALUE valueType, String comment, StandardCommentReplacement... replacements) {
628         this(null, status, hdu, valueType, comment, replacements);
629     }
630 
631     Standard(String headerName, SOURCE status, HDU hdu, VALUE valueType, String comment,
632             StandardCommentReplacement... replacements) {
633         key = new FitsKey(headerName == null ? name() : headerName, status, hdu, valueType, comment);
634         commentReplacements = replacements;
635         FitsKey.registerStandard(this);
636     }
637 
638     @Override
639     public final FitsKey impl() {
640         return key;
641     }
642 
643     @Override
644     public String comment() {
645         Class<?> contextClass = COMMENT_CONTEXT.get();
646         if (contextClass == null) {
647             contextClass = Object.class;
648         }
649         for (StandardCommentReplacement stdCommentReplacement : commentReplacements) {
650             if (stdCommentReplacement.getContext().isAssignableFrom(contextClass)) {
651                 if (stdCommentReplacement.getComment() != null) {
652                     return stdCommentReplacement.getComment();
653                 }
654             }
655         }
656         return key.comment();
657     }
658 
659     /**
660      * @deprecated       (<i>for internal use</i>) Using {@link nom.tam.fits.HeaderCard#setComment(String)} after
661      *                       creating a header card with this keyword provides a more transparent way of setting
662      *                       context-specific comments. This convoluted approach is no longer supported and will be
663      *                       removed in the future.
664      * 
665      * @param      clazz Usually a subclass of <code>nom.tam.fits.Data</code>.
666      * 
667      * @see              nom.tam.fits.HeaderCard#setComment(String)
668      */
669     public static void context(Class<?> clazz) {
670         COMMENT_CONTEXT.set(clazz);
671     }
672 
673     /**
674      * scan for a comment with the specified reference key.
675      *
676      * @param      commentKey the reference key
677      *
678      * @return                the comment for the reference key
679      * 
680      * @deprecated            (<i>)for internal use</i>)
681      */
682     public String getCommentByKey(String commentKey) {
683         for (StandardCommentReplacement commentReplacement : commentReplacements) {
684             if (commentReplacement.getRef().equals(commentKey)) {
685                 String foundcommentReplacement = commentReplacement.getComment();
686                 if (foundcommentReplacement == null) {
687                     return comment();
688                 }
689                 return foundcommentReplacement;
690             }
691         }
692         return null;
693     }
694 
695     /**
696      * set the comment for the specified reference key.
697      *
698      * @param      commentKey the reference key
699      * @param      value      the comment to set when the fits key is used.
700      * 
701      * @deprecated            (<i>)for internal use</i>)
702      */
703     public void setCommentByKey(String commentKey, String value) {
704         for (StandardCommentReplacement commentReplacement : commentReplacements) {
705             if (commentReplacement.getRef().equals(commentKey)) {
706                 commentReplacement.setComment(value);
707                 return;
708             }
709         }
710     }
711 
712     private static StandardCommentReplacement replaceable(String string, Class<?> clazz) {
713         return new StandardCommentReplacement(string, clazz);
714     }
715 
716     private static StandardCommentReplacement replaceable(String string, Class<?> clazz, String comment) {
717         return new StandardCommentReplacement(string, clazz, comment);
718     }
719 
720     /**
721      * Returns the standard FITS keyword that matches the specified actual key.
722      * 
723      * @param  key The key as it may appear in a FITS header, e.g. "CTYPE1A"
724      * 
725      * @return     The standard FITS keyword/pattern that matches, e.g. {@link WCS#CTYPEna}.
726      * 
727      * @see        IFitsHeader#extractIndices(String)
728      * 
729      * @since      1.19
730      */
731     public static IFitsHeader match(String key) {
732         return FitsKey.matchStandard(key);
733     }
734 
735 }