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     @Deprecated
229     EPOCH(SOURCE.RESERVED, HDU.ANY, VALUE.REAL, "[yr] equinox of celestial coordinate system"),
230 
231     /**
232      * The value field shall contain a floating point number giving the equinox in years for the celestial coordinate
233      * system in which positions are expressed. This version of the keyword does not support alternative coordinate
234      * systems.
235      * 
236      * @see WCS#EQUINOXa
237      */
238     EQUINOX(SOURCE.RESERVED, HDU.ANY, VALUE.REAL, "[yr] equinox of celestial coordinate system"),
239 
240     /**
241      * If the FITS file may contain extensions, a card image with the keyword EXTEND and the value field containing the
242      * logical value T must appear in the primary key immediately after the last NAXISn card image, or, if NAXIS=0, the
243      * NAXIS card image. The presence of this keyword with the value T in the primary key does not require that
244      * extensions be present.
245      */
246     EXTEND(SOURCE.INTEGRAL, HDU.PRIMARY, VALUE.LOGICAL, "allow extensions"),
247 
248     /**
249      * The value field shall contain an integer, specifying the level in a hierarchy of extension levels of the
250      * extension key containing it. The value shall be 1 for the highest level; levels with a higher value of this
251      * keyword shall be subordinate to levels with a lower value. If the EXTLEVEL keyword is absent, the file should be
252      * treated as if the value were 1. This keyword is used to describe an extension and should not appear in the
253      * primary key.RANGE: [1:] DEFAULT: 1
254      */
255     EXTLEVEL(SOURCE.RESERVED, HDU.ANY, VALUE.INTEGER, "hierarchical level of the extension"),
256 
257     /**
258      * The value field shall contain a character string, to be used to distinguish among different extensions of the
259      * same type, i.e., with the same value of XTENSION, in a FITS file. This keyword is used to describe an extension
260      * and but may appear in the primary header also.
261      */
262     EXTNAME(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "HDU name"),
263 
264     /**
265      * The value field shall contain an integer, to be used to distinguish among different extensions in a FITS file
266      * with the same type and name, i.e., the same values for XTENSION and EXTNAME. The values need not start with 1 for
267      * the first extension with a particular value of EXTNAME and need not be in sequence for subsequent values. If the
268      * EXTVER keyword is absent, the file should be treated as if the value were 1. This keyword is used to describe an
269      * extension and should not appear in the primary key.RANGE: [1:] DEFAULT: 1
270      */
271     EXTVER(SOURCE.RESERVED, HDU.ANY, VALUE.INTEGER, "HDU version"),
272 
273     /**
274      * The value field shall contain an integer that shall be used in any way appropriate to define the data structure,
275      * consistent with Eq. 5.2 in the FITS Standard. This keyword originated for use in FITS Random Groups where it
276      * specifies the number of random groups present. In most other cases this keyword will have the value 1.
277      */
278     GCOUNT(SOURCE.MANDATORY, HDU.ANY, VALUE.INTEGER, "group count",
279             replaceable("randomgroupsdata:groups", RandomGroupsData.class), //
280             replaceable("undefineddata:groups", UndefinedData.class), //
281             replaceable("header:groups", RandomGroupsData.class)//
282     ),
283 
284     /**
285      * The value field shall contain the logical constant T. The value T associated with this keyword implies that
286      * random groups records are present.
287      */
288     GROUPS(SOURCE.MANDATORY, HDU.GROUPS, VALUE.LOGICAL, "random groups data", //
289             replaceable("randomgroupsdata:groups", RandomGroupsData.class)//
290     ),
291 
292     /**
293      * This keyword shall have no associated value; columns 9-80 may contain any ASCII text. The text should contain a
294      * history of steps and procedures associated with the processing of the associated data. Any number of HISTORY card
295      * images may appear in a key.
296      */
297     HISTORY(SOURCE.RESERVED, HDU.ANY, VALUE.NONE, "processing history of the data"),
298 
299     /**
300      * The value field shall contain a character string identifying the instrument used to acquire the data associated
301      * with the key.
302      */
303     INSTRUME(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "name of instrument"),
304 
305     /**
306      * The value field shall contain a non-negative integer no greater than 999, representing the number of axes in the
307      * associated data array. A value of zero signifies that no data follow the key in the HDU. In the context of FITS
308      * 'TABLE' or 'BINTABLE' extensions, the value of NAXIS is always 2.RANGE: [0:999]
309      */
310     NAXIS(SOURCE.MANDATORY, HDU.ANY, VALUE.INTEGER, "dimensionality of data"),
311 
312     /**
313      * The value field of this indexed keyword shall contain a non-negative integer, representing the number of elements
314      * along axis n of a data array. The NAXISn must be present for all values n = 1,...,NAXIS, and for no other values
315      * 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
316      * to 0, there should not be any NAXISn keywords.RANGE: [0:]
317      */
318     NAXISn(SOURCE.MANDATORY, HDU.ANY, VALUE.INTEGER, "n'th data dimension", //
319             replaceable("tablehdu:naxis1", TableData.class, "Size of table row in bytes"), //
320             replaceable("tablehdu:naxis2", TableData.class, "Number of table rows"),
321             replaceable("header:naxis2", Object.class)),
322 
323     /**
324      * The value field shall contain a character string giving a name for the object observed.
325      */
326     OBJECT(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "name of observed object"),
327 
328     /**
329      * The value field shall contain a character string identifying who acquired the data associated with the key.
330      */
331     OBSERVER(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "observer(s) who acquired the data"),
332 
333     /**
334      * The value field shall contain a character string identifying the organization or institution responsible for
335      * creating the FITS file.
336      */
337     ORIGIN(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "organization responsible for the data"),
338 
339     /**
340      * The value field shall contain an integer that shall be used in any way appropriate to define the data structure,
341      * consistent with Eq. 5.2 in the FITS Standard. This keyword was originated for use with FITS Random Groups and
342      * represented the number of parameters preceding each group. It has since been used in 'BINTABLE' extensions to
343      * represent the size of the data heap following the main data table. In most other cases its value will be zero.
344      */
345     PCOUNT(SOURCE.MANDATORY, HDU.ANY, VALUE.INTEGER, "associated parameter count", //
346             replaceable("binarytable:pcount", TableData.class, "heap size in bytes"),
347             replaceable("randomgroups:pcount", RandomGroupsData.class, "parameter values per group"),
348             replaceable("undefineddata:pcount", UndefinedData.class), replaceable("header:pcount", Object.class)),
349 
350     /**
351      * This keyword is reserved for use within the FITS Random Groups structure. This keyword shall be used, along with
352      * the PZEROn keyword, when the nth FITS group parameter value is not the true physical value, to transform the
353      * group parameter value to the true physical values it represents, using the equation, physical_value = PZEROn +
354      * PSCALn * group_parameter_value. The value field shall contain a floating point number representing the
355      * coefficient of the linear term, the scaling factor between true values and group parameter values at zero offset.
356      * The default value for this keyword is 1.0.
357      */
358     PSCALn(SOURCE.INTEGRAL, HDU.GROUPS, VALUE.REAL, "parameter quantization scaling"),
359 
360     /**
361      * This keyword is reserved for use within the FITS Random Groups structure. The value field shall contain a
362      * character string giving the name of parameter n. If the PTYPEn keywords for more than one value of n have the
363      * same associated name in the value field, then the data value for the parameter of that name is to be obtained by
364      * adding the derived data values of the corresponding parameters. This rule provides a mechanism by which a random
365      * parameter may have more precision than the accompanying data array elements; for example, by summing two 16-bit
366      * values with the first scaled relative to the other such that the sum forms a number of up to 32-bit precision.
367      */
368     PTYPEn(SOURCE.INTEGRAL, HDU.GROUPS, VALUE.STRING, "name of random groups parameter"),
369 
370     /**
371      * This keyword is reserved for use within the FITS Random Groups structure. This keyword shall be used, along with
372      * the PSCALn keyword, when the nth FITS group parameter value is not the true physical value, to transform the
373      * group parameter value to the physical value. The value field shall contain a floating point number, representing
374      * the true value corresponding to a group parameter value of zero. The default value for this keyword is 0.0. The
375      * transformation equation is as follows: physical_value = PZEROn + PSCALn * group_parameter_value.DEFAULT: 0.0
376      */
377     PZEROn(SOURCE.INTEGRAL, HDU.GROUPS, VALUE.REAL, "parameter quantization offset"),
378 
379     /**
380      * Coordinate reference frame of major/minor axes.If absent the default value is 'FK5'. This version of the keyword
381      * does not support alternative coordinate systems.
382      * 
383      * @see WCS#RADESYSa
384      */
385     RADESYS(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "celestial coordinate reference frame"),
386 
387     /**
388      * Coordinate reference frame of major/minor axes (generic).
389      *
390      * @deprecated Deprecated in the current FITS satndard, use {@link #RADESYS} instead.
391      */
392     @Deprecated
393     RADECSYS(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "celestial coordinate reference frame"),
394 
395     /**
396      * [Hz] Rest frequency of observed spectral line.
397      * 
398      * @since 1.19
399      * 
400      * @see   WCS#RESTFRQa
401      */
402     RESTFRQ(SOURCE.RESERVED, HDU.IMAGE, VALUE.REAL, "[Hz] line rest frequency"),
403 
404     /**
405      * [Hz] Rest frequeny of observed spectral line (generic).
406      *
407      * @deprecated Deprecated in the current FITS standard, use {@link #RESTFRQ} instead.
408      */
409     @Deprecated
410     RESTFREQ(SOURCE.RESERVED, HDU.ANY, VALUE.REAL, "[Hz] observed line rest frequency"),
411 
412     /**
413      * The value field shall contain a character string citing a reference where the data associated with the key are
414      * published.
415      */
416     REFERENC(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "bibliographic reference"),
417 
418     /**
419      * The SIMPLE keyword is required to be the first keyword in the primary key of all FITS files. The value field
420      * shall contain a logical constant with the value T if the file conforms to the standard. This keyword is mandatory
421      * for the primary key and is not permitted in extension headers. A value of F signifies that the file does not
422      * conform to this standard.
423      */
424     SIMPLE(SOURCE.MANDATORY, HDU.PRIMARY, VALUE.LOGICAL, "primary HDU", //
425             replaceable("header:simple", Object.class, "Java FITS: " + new java.util.Date())//
426     ),
427 
428     /**
429      * The value field of this indexed keyword shall contain an integer specifying the column in which field n starts in
430      * an ASCII TABLE extension. The first column of a row is numbered 1.RANGE: [1:]
431      */
432     TBCOLn(SOURCE.MANDATORY, HDU.ASCII_TABLE, VALUE.INTEGER, "column byte offset", //
433             replaceable("asciitable:tbcolN", AsciiTable.class)//
434     ),
435 
436     /**
437      * The value field of this indexed keyword shall contain a character string describing how to interpret the contents
438      * of field n as a multidimensional array, providing the number of dimensions and the length along each axis. The
439      * form of the value is not further specified by the Standard. A proposed convention is described in Appendix B.2 of
440      * the FITS Standard in which the value string has the format '(l,m,n...)' where l, m, n,... are the dimensions of
441      * the array.
442      */
443     TDIMn(SOURCE.RESERVED, HDU.BINTABLE, VALUE.STRING, "dimensionality of column array elements", //
444             replaceable("binarytable:tdimN", BinaryTable.class)//
445     ),
446 
447     /**
448      * The value field of this indexed keyword shall contain a character string describing the format recommended for
449      * the display of the contents of field n. If the table value has been scaled, the physical value shall be
450      * displayed. All elements in a field shall be displayed with a single, repeated format. For purposes of display,
451      * each byte of bit (type X) and byte (type B) arrays is treated as an unsigned integer. Arrays of type A may be
452      * terminated with a zero byte. Only the format codes in Table 8.6, discussed in section 8.3.4 of the FITS Standard,
453      * are permitted for encoding. The format codes must be specified in upper case. If the Bw.m, Ow.m, and Zw.m formats
454      * are not readily available to the reader, the Iw.m display format may be used instead, and if the ENw.d and ESw.d
455      * formats are not available, Ew.d may be used. The meaning of this keyword is not defined for fields of type P in
456      * the Standard but may be defined in conventions using such fields.
457      */
458     TDISPn(SOURCE.RESERVED, HDU.TABLE, VALUE.STRING, "column display format"),
459 
460     /**
461      * The value field shall contain a character string identifying the telescope used to acquire the data associated
462      * with the key.
463      */
464     TELESCOP(SOURCE.RESERVED, HDU.ANY, VALUE.STRING, "name of telescope / observatory"),
465 
466     /**
467      * The value field shall contain a non-negative integer representing the number of fields in each row of a 'TABLE'
468      * or 'BINTABLE' extension. The maximum permissible value is 999. RANGE: [0:999]
469      */
470     TFIELDS(SOURCE.MANDATORY, HDU.TABLE, VALUE.INTEGER, "number of columns in the table"),
471 
472     /**
473      * The value field of this indexed keyword shall contain a character string describing the format in which field n
474      * is encoded in a 'TABLE' or 'BINTABLE' extension.
475      */
476     TFORMn(SOURCE.MANDATORY, HDU.TABLE, VALUE.STRING, "column data format", //
477             replaceable("asciitable:tformN", AsciiTable.class), //
478             replaceable("binarytable:tformN", BinaryTable.class)//
479     ),
480 
481     /**
482      * The value field of this keyword shall contain an integer providing the separation, in bytes, between the start of
483      * the main data table and the start of a supplemental data area called the heap. The default value shall be the
484      * product of the values of NAXIS1 and NAXIS2. This keyword shall not be used if the value of PCOUNT is zero. A
485      * proposed application of this keyword is presented in Appendix B.1 of the FITS Standard.
486      */
487     THEAP(SOURCE.INTEGRAL, HDU.BINTABLE, VALUE.INTEGER, "heap byte offset", //
488             replaceable("binarytable:theap", BinaryTable.class)//
489     ),
490 
491     /**
492      * In ASCII 'TABLE' extensions, the value field for this indexed keyword shall contain the character string that
493      * represents an undefined value for field n. The string is implicitly blank filled to the width of the field. In
494      * binary 'BINTABLE' table extensions, the value field for this indexed keyword shall contain the integer that
495      * represents an undefined value for field n of data type B, I, or J. The keyword may not be used in 'BINTABLE'
496      * extensions if field n is of any other data type.
497      */
498     TNULLn(SOURCE.INTEGRAL, HDU.TABLE, VALUE.ANY, "column value for undefined elements"),
499 
500     /**
501      * This indexed keyword shall be used, along with the TZEROn keyword, when the quantity in field n does not
502      * represent a true physical quantity. The value field shall contain a floating point number representing the
503      * coefficient of the linear term in the equation, physical_value = TZEROn + TSCALn * field_value, which must be
504      * used to compute the true physical value of the field, or, in the case of the complex data types C and M, of the
505      * real part of the field with the imaginary part of the scaling factor set to zero. The default value for this
506      * keyword is 1.0. This keyword may not be used if the format of field n is A, L, or X.DEFAULT: 1.0
507      */
508     TSCALn(SOURCE.RESERVED, HDU.TABLE, VALUE.REAL, "column quantization scaling"),
509 
510     /**
511      * The value field for this indexed keyword shall contain a character string, giving the name of field n. It is
512      * recommended that only letters, digits, and underscore (hexadecimal code 5F, ('_') be used in the name. String
513      * comparisons with the values of TTYPEn keywords should not be case sensitive. The use of identical names for
514      * different fields should be avoided.
515      */
516     TTYPEn(SOURCE.RESERVED, HDU.TABLE, VALUE.STRING, "column name"),
517 
518     /**
519      * The value field shall contain a character string describing the physical units in which the quantity in field n,
520      * after any application of TSCALn and TZEROn, is expressed. The units of all FITS key keyword values, with the
521      * exception of measurements of angles, should conform with the recommendations in the IAU Style Manual. For angular
522      * measurements given as floating point values and specified with reserved keywords, degrees are the recommended
523      * units (with the units, if specified, given as 'deg').
524      */
525     TUNITn(SOURCE.RESERVED, HDU.TABLE, VALUE.STRING, "column physical unit"),
526 
527     /**
528      * This indexed keyword shall be used, along with the TSCALn keyword, when the quantity in field n does not
529      * represent a true physical quantity. The value field shall contain a floating point number representing the true
530      * physical value corresponding to a value of zero in field n of the FITS file, or, in the case of the complex data
531      * types C and M, in the real part of the field, with the imaginary part set to zero. The default value for this
532      * keyword is 0.0. This keyword may not be used if the format of field n is A, L, or X.DEFAULT: 0.0
533      */
534     TZEROn(SOURCE.RESERVED, HDU.TABLE, VALUE.REAL, "column quantization offset"),
535 
536     /**
537      * The value field of this indexed keyword shall contain a floating point number specifying the maximum valid
538      * physical value represented in column n of the table, exclusive of any special values. This keyword may only be
539      * used in 'TABLE' or 'BINTABLE' extensions and is analogous to the DATAMAX keyword used for FITS images.
540      * 
541      * @since 1.19
542      */
543     TDMAXn(SOURCE.RESERVED, HDU.TABLE, VALUE.REAL, "maximum value in the column"),
544 
545     /**
546      * The value field of this indexed keyword shall contain a floating point number specifying the minimum valid
547      * physical value represented in column n of the table, exclusive of any special values. This keyword may only be
548      * used in 'TABLE' or 'BINTABLE' extensions and is analogous to the DATAMIN keyword used for FITS images.
549      * 
550      * @since 1.19
551      */
552     TDMINn(SOURCE.RESERVED, HDU.TABLE, VALUE.REAL, "minimum value in the column"),
553 
554     /**
555      * The value field of this indexed keyword shall contain a floating point number specifying the upper bound of the
556      * legal range of physical values that may be represented in column n of the table. The column may contain values
557      * that are greater than this legal maximum value but the interpretation of such values is not defined here. The
558      * value of this keyword is typically used as the maxinum value when constructing a histogram of the values in the
559      * column. This keyword may only be used in 'TABLE' or 'BINTABLE' extensions.
560      * 
561      * @since 1.19
562      */
563     TLMAXn(SOURCE.RESERVED, HDU.TABLE, VALUE.REAL, "maximum legal value in the column"),
564 
565     /**
566      * The value field of this indexed keyword shall contain a floating point number specifying the lower bound of the
567      * legal range of physical values that may be represented in column n of the table. The column may contain values
568      * that are less than this legal minimum value but the interpretation of such values is not defined here. The value
569      * of this keyword is typically used as the mininum value when constructing a histogram of the values in the column.
570      * This keyword may only be used in 'TABLE' or 'BINTABLE' extensions.
571      * 
572      * @since 1.19
573      */
574     TLMINn(SOURCE.RESERVED, HDU.TABLE, VALUE.REAL, "minimum legal value in the column"),
575 
576     /**
577      * The value field shall contain a character string giving the name of the extension type. This keyword is mandatory
578      * for an extension key and must not appear in the primary key. For an extension that is not a standard extension,
579      * the type name must not be the same as that of a standard extension.
580      */
581     XTENSION(SOURCE.MANDATORY, HDU.EXTENSION, VALUE.STRING, "HDU extension type",
582             replaceable("imagedata:xtension", ImageData.class, "image HDU"), //
583             replaceable("binarytable:xtension", BinaryTable.class, "binary table HDU"), //
584             replaceable("asciitable:xtension", AsciiTable.class, "ASCII table HDU"), //
585             replaceable("undefineddata:xtension", UndefinedData.class), //
586             replaceable("header:xtension", Object.class)//
587     ),
588 
589     /**
590      * If set to <code>true</code>, it indicates that the HDU should inherit all non-confliucting keywords from the
591      * primary HDU.
592      * 
593      * @since 1.19
594      */
595     INHERIT(SOURCE.RESERVED, HDU.EXTENSION, VALUE.LOGICAL, "inherit primary header entries");
596 
597     private static final ThreadLocal<Class<?>> COMMENT_CONTEXT = new ThreadLocal<>();
598 
599     /**
600      * A shorthand for {@link #NAXISn}<code>.n(1)</code>, that is the regular dimension along the first, fastest FITS
601      * array index (this is the same as the last dimension of Java arrays).
602      */
603     public static final IFitsHeader NAXIS1 = NAXISn.n(1);
604 
605     /**
606      * A shorthand for {@link #NAXISn}<code>.n(2)</code>, that is the regular dimension along the second fastest FITS
607      * array index (this is the same as the one before the last dimension of Java arrays).
608      */
609     public static final IFitsHeader NAXIS2 = NAXISn.n(2);
610 
611     /**
612      * The value of the XTENSION keword in case of a binary table.
613      */
614     public static final String XTENSION_ASCIITABLE = "TABLE";
615 
616     /**
617      * The value of the XTENSION keword in case of a binary table.
618      */
619     public static final String XTENSION_BINTABLE = "BINTABLE";
620 
621     /**
622      * The value of the XTENSION keword in case of an image.
623      */
624     public static final String XTENSION_IMAGE = "IMAGE";
625 
626     private final StandardCommentReplacement[] commentReplacements;
627 
628     private final FitsKey key;
629 
630     Standard(SOURCE status, HDU hdu, VALUE valueType, String comment, StandardCommentReplacement... replacements) {
631         this(null, status, hdu, valueType, comment, replacements);
632     }
633 
634     Standard(String headerName, SOURCE status, HDU hdu, VALUE valueType, String comment,
635             StandardCommentReplacement... replacements) {
636         key = new FitsKey(headerName == null ? name() : headerName, status, hdu, valueType, comment);
637         commentReplacements = replacements;
638         FitsKey.registerStandard(this);
639     }
640 
641     @Override
642     public final FitsKey impl() {
643         return key;
644     }
645 
646     @Override
647     public String comment() {
648         Class<?> contextClass = COMMENT_CONTEXT.get();
649         if (contextClass == null) {
650             contextClass = Object.class;
651         }
652         for (StandardCommentReplacement stdCommentReplacement : commentReplacements) {
653             if (stdCommentReplacement.getContext().isAssignableFrom(contextClass)) {
654                 if (stdCommentReplacement.getComment() != null) {
655                     return stdCommentReplacement.getComment();
656                 }
657             }
658         }
659         return key.comment();
660     }
661 
662     /**
663      * @deprecated       (<i>for internal use</i>) Using {@link nom.tam.fits.HeaderCard#setComment(String)} after
664      *                       creating a header card with this keyword provides a more transparent way of setting
665      *                       context-specific comments. This convoluted approach is no longer supported and will be
666      *                       removed in the future.
667      * 
668      * @param      clazz Usually a subclass of <code>nom.tam.fits.Data</code>.
669      * 
670      * @see              nom.tam.fits.HeaderCard#setComment(String)
671      */
672     @Deprecated
673     public static void context(Class<?> clazz) {
674         COMMENT_CONTEXT.set(clazz);
675     }
676 
677     /**
678      * scan for a comment with the specified reference key.
679      *
680      * @param      commentKey the reference key
681      *
682      * @return                the comment for the reference key
683      * 
684      * @deprecated            (<i>)for internal use</i>)
685      */
686     @Deprecated
687     public String getCommentByKey(String commentKey) {
688         for (StandardCommentReplacement commentReplacement : commentReplacements) {
689             if (commentReplacement.getRef().equals(commentKey)) {
690                 String foundcommentReplacement = commentReplacement.getComment();
691                 if (foundcommentReplacement == null) {
692                     return comment();
693                 }
694                 return foundcommentReplacement;
695             }
696         }
697         return null;
698     }
699 
700     /**
701      * set the comment for the specified reference key.
702      *
703      * @param      commentKey the reference key
704      * @param      value      the comment to set when the fits key is used.
705      * 
706      * @deprecated            (<i>)for internal use</i>)
707      */
708     @Deprecated
709     public void setCommentByKey(String commentKey, String value) {
710         for (StandardCommentReplacement commentReplacement : commentReplacements) {
711             if (commentReplacement.getRef().equals(commentKey)) {
712                 commentReplacement.setComment(value);
713                 return;
714             }
715         }
716     }
717 
718     private static StandardCommentReplacement replaceable(String string, Class<?> clazz) {
719         return new StandardCommentReplacement(string, clazz);
720     }
721 
722     private static StandardCommentReplacement replaceable(String string, Class<?> clazz, String comment) {
723         return new StandardCommentReplacement(string, clazz, comment);
724     }
725 
726     /**
727      * Returns the standard FITS keyword that matches the specified actual key.
728      * 
729      * @param  key The key as it may appear in a FITS header, e.g. "CTYPE1A"
730      * 
731      * @return     The standard FITS keyword/pattern that matches, e.g. {@link WCS#CTYPEna}.
732      * 
733      * @see        IFitsHeader#extractIndices(String)
734      * 
735      * @since      1.19
736      */
737     public static IFitsHeader match(String key) {
738         return FitsKey.matchStandard(key);
739     }
740 
741 }