All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nom.tam.fits.header.IFitsHeader Maven / Gradle / Ivy

Go to download

Java library for reading and writing FITS files. FITS, the Flexible Image Transport System, is the format commonly used in the archiving and transport of astronomical data.

There is a newer version: 1.21.0
Show newest version
package nom.tam.fits.header;

import java.util.NoSuchElementException;

import nom.tam.fits.HeaderCard;

/*
 * #%L
 * INDI for Java Utilities for the fits image format
 * %%
 * Copyright (C) 2012 - 2015 indiforjava
 * %%
 * This is free and unencumbered software released into the public domain.
 *
 * Anyone is free to copy, modify, publish, use, compile, sell, or
 * distribute this software, either in source code form or as a compiled
 * binary, for any purpose, commercial or non-commercial, and by any
 * means.
 *
 * In jurisdictions that recognize copyright laws, the author or authors
 * of this software dedicate any and all copyright interest in the
 * software to the public domain. We make this dedication for the benefit
 * of the public at large and to the detriment of our heirs and
 * successors. We intend this dedication to be an overt act of
 * relinquishment in perpetuity of all present and future rights to this
 * software under copyright law.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 * #L%
 */

/**
 * Interface for standardized header keyword implementations. Standardized header keys help with proper usage, with
 * restricted use and value types as appropriate. Using keywords that implement this interface make it less likely for
 * one to end up with inproperly constructed FITS files. Therefore, their usage is highly encouranged when possible.
 * 
 * @see HeaderCard#setValueCheckingPolicy(nom.tam.fits.HeaderCard.ValueCheck)
 * @see nom.tam.fits.Header#setKeywordChecking(nom.tam.fits.Header.KeywordCheck)
 */
public interface IFitsHeader {

    /** Max numeric index we may use to replace n in the Java name of indexed variables. */
    int MAX_INDEX = 999;

    /** An enumeration of HDU types in which a header keyword may be used. */
    enum HDU {
        /** keyword may be used in any HDU */
        ANY,
        /** image and/or random groups keywords */
        IMAGE,
        /** keyword for random groups only */
        GROUPS,
        /** Generic table keyword, can be used both in ASCII and binary tables */
        TABLE,
        /** keyword for ASCII tables only */
        ASCII_TABLE,
        /** keyword for binary tables */
        BINTABLE,
        /** keyword must appear in the primary HDU only */
        PRIMARY,
        /** keyword must appear in extension HDUs only */
        EXTENSION,
        /** @deprecated Use {@link #ANY} instead. */
        PRIMARY_EXTENSION;

    }

    /** Documentation sources for the various known conventions. */
    enum SOURCE {
        /**
         * Checksum keywords. See
         * checksum doc
         */
        CHECKSUM("http://heasarc.gsfc.nasa.gov/docs/heasarc/ofwg/docs/general/checksum/checksum.html"),

        /**
         * CXC keywords. See http://cxc.harvard.edu/contrib/arots/fits/content.txt
         */
        CXC("http://cxc.harvard.edu/contrib/arots/fits/content.txt"),
        /**
         * ESO keywords. See http://arcdev.hq.eso.org/dicb/dicd/dic-1-1.4.html
         */
        ESO("http://arcdev.hq.eso.org/dicb/dicd/dic-1-1.4.html"),
        /**
         * HEASARC keywords. See http://heasarc.gsfc.nasa.gov/docs/heasarc/ofwg/docs/ofwg_recomm/r13.html
         */
        HEASARC("http://heasarc.gsfc.nasa.gov/docs/heasarc/ofwg/docs/ofwg_recomm/r13.html"),
        /**
         * The keyword is integral to the workings of the library. Users should not attempt set set or modify.
         */
        INTEGRAL(null),
        /**
         * Mandatory keywords defined by the FITS standard.
         */
        MANDATORY("http://heasarc.gsfc.nasa.gov/docs/fcg/standard_dict.html"),
        /**
         * MaxImDL keywords. See http://www.cyanogen.com/help/maximdl/FITS_File_Header_Definitions.htm
         */
        MaxImDL("http://www.cyanogen.com/help/maximdl/FITS_File_Header_Definitions.htm"),
        /**
         * NOAO keywords. See http://iraf.noao.edu/iraf/web/projects/ccdmosaic/imagedef/fitsdic.html
         */
        NOAO("http://iraf.noao.edu/iraf/web/projects/ccdmosaic/imagedef/fitsdic.html"),
        /**
         * Reserved keywords specified by the FITS standard.
         */
        RESERVED("http://heasarc.gsfc.nasa.gov/docs/fcg/standard_dict.html"),
        /**
         * ROSAT keywords. (No link available.)
         */
        ROSAT(null),
        /**
         * SBIG keywords. See http://archive.sbig.com/pdffiles/SBFITSEXT_1r0.pdf
         */
        SBIG("http://archive.sbig.com/pdffiles/SBFITSEXT_1r0.pdf"),
        /**
         * STScI keywords. See http://tucana.noao.edu/ADASS/adass_proc/adass_95/zaraten/zaraten.html
         */
        STScI("http://tucana.noao.edu/ADASS/adass_proc/adass_95/zaraten/zaraten.html"),
        /**
         * UCOLICK keywords. See http://www.ucolick.org
         */
        UCOLICK("http://www.ucolick.org"),
        /**
         * developed over time, source long forgotten.
         */
        UNKNOWN(null);

        private final String url;

        SOURCE(String url) {
            this.url = url;
        }

        /**
         * Returns the URL that defines this particular header value, which may be null.
         * 
         * @return The URL that contains the keyword specification or null if unknown or undefined.
         */
        public String url() {
            return url;
        }
    }

    /** Values types to which implementing keywords can be restricted to. */
    enum VALUE {
        /** The keyword takes no value (i.e. END or comment-style keywords */
        NONE,

        /** keyword expects a logical 'T' or 'F' value */
        LOGICAL,

        /** keyword expects a String value */
        STRING,

        /** keyword expects an integer type value */
        INTEGER,

        /** keyword expects a floating-point value (integers allowed). */
        REAL,

        /** keyword expects a complex value */
        COMPLEX,

        /** The keyword may be used with any value type */
        ANY
    }

    /**
     * (primarily for internal use) Returns the concrete implementation of this header entry, which provides
     * implementation of access methods.
     * 
     * @return the implementation of this keyword, which provides the actual access methods. Implementations of this
     *             interface should simply return themselves.
     * 
     * @since  1.19
     */
    default FitsKey impl() {
        return null;
    }

    /**
     * Returns the comment associated to this FITS header entry. The comment is entirely optional, and it may not be
     * appear in full (or at all) in the FITS header. Comments should thus never contain essential information. Their
     * purpose is only to provide non-essential extra information for human use.
     * 
     * @return the associated standard comment.
     * 
     * @see    HeaderCard#getComment()
     * @see    HeaderCard#setComment(String)
     */
    default String comment() {
        return impl().comment();
    }

    /**
     * Returns the type of HDU(s) in which this header entry may be used.
     * 
     * @return the HDU type(s) that this keyword may support.
     */
    default HDU hdu() {
        return impl().hdu();
    }

    /**
     * 

* Returns the FITS header keyword (or keyword template) for this header entry. Standard FITS keywords are limited * to 8 characters, and contain only epper-case letters, numbers, hyphen, and underscore characters. Lower-case 'n' * characters may be included as placeholders for indexing conventions that must be filled before the keyword may be * used in headers and/or header cards. *

* * @return the FITS header keyword for this entry. The returned keyword may include an indexing pattern (lower-case * 'n' characters), which may need to be filled via {@link #n(int...)} before the keyword may be used to * construct header cards or be used in FITS headers. (Alternative coordinate markers, via lower case * 'a' at the end of the keyword definition, are stripped and should not be included in the returned * keyword name pattern.) * * @see #n(int...) */ default String key() { return impl().key(); } /** * Constructs an indexed FITS header keyword entry from this stem, replacing index place-holders (indicated by * lower-case 'n' in the name) with actual numerical values. Numbering for FITS header keywords always starts from * 1, and should never exceed 999. Note, that for keywords that have multiple indices, you may specify them all in a * single call, or may use successive calls to fill indices in the order they appear (the latter is somewhat less * efficient, but still entirely legal). * * @param numbers the 1-based indices to add to the stem, in the order they appear in the the * enum name. * * @return an indexed instance of this FITS header entry * * @throws IndexOutOfBoundsException if the index is less than 0 or exceeds 999. (In truth we should throw an * exception for 0 as well, but seems to be common not-quite-legal FITS usage * with 0 indices. Hence we relax the condition). * @throws IllegalStateException if the resulting indexed keyword exceeds the maximum 8-bytes allowed for * standard FITS keywords. * @throws NoSuchElementException If more indices were supplied than can be filled for this keyword. * * @see #extractIndices(String) */ default IFitsHeader n(int... numbers) throws IndexOutOfBoundsException, NoSuchElementException, IllegalStateException { StringBuffer headerName = new StringBuffer(key()); for (int number : numbers) { if (number < 0 || number > MAX_INDEX) { throw new IndexOutOfBoundsException(key() + ": index " + number + " is out of bounds."); } int indexOfN = headerName.indexOf("n"); if (indexOfN < 0) { throw new NoSuchElementException("Too many indices (" + numbers.length + ") supplied for " + key()); } headerName.replace(indexOfN, indexOfN + 1, Integer.toString(number)); } if (headerName.length() > HeaderCard.MAX_KEYWORD_LENGTH) { throw new IllegalStateException("indexed keyword " + headerName.toString() + " is too long."); } return new FitsKey(headerName.toString(), status(), hdu(), valueType(), comment()); } /** * Returns the standard convention, which defines this FITS header entry * * @return the standard or convention that specifies this FITS heacer keyword */ default SOURCE status() { return impl().status(); } /** * The type(s) of value(s) this FITS header entry might take. * * @return the value type(s) for this FITS header entry */ default VALUE valueType() { return impl().valueType(); } /** * Extracts the indices for this stndardized key from an actual keyword realization. The keyword realization must be * match the indexing and/or alternative coordinate system pattern for this key, or else an exception will be * thrown. * * @param key The actual keyword as it appears in a FITS header * * @return An array of indices that appear in the key, or null if the keyword * is not one that can be indexed. * * @throws IllegalArgumentException if the keyword does not match the pattern of this standardized FITS key * * @see #n(int...) * @see Standard#match(String) * * @since 1.19 */ default int[] extractIndices(String key) throws IllegalArgumentException { String pattern = key(); int i, j = 0, lp = pattern.length(), lk = key.length(); int n = 0; for (i = 0; i < lp; i++) { if (pattern.charAt(i) == 'n') { n++; } } if (n == 0) { return null; } int[] idx = new int[n]; for (i = 0, n = 0; i < lp; i++) { if (pattern.charAt(i) == 'n') { if (i + 1 < lp && pattern.charAt(i + 1) == 'n') { idx[n++] = key.charAt(j++) - '0'; } else { int value = 0; while (j < lk && Character.isDigit(key.charAt(j))) { value = FitsKey.BASE_10 * value + key.charAt(j++) - '0'; } idx[n++] = value; } } else if (key.charAt(j++) != pattern.charAt(i)) { throw new IllegalArgumentException("Key " + key + " does no match pattern " + pattern); } } return idx; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy