package nom.tam.fits; /* * Copyright: Thomas McGlynn 1997-1998. * This code may be used for any purpose, non-commercial * or commercial so long as this copyright notice is retained * in the source code or included in or referred to in any * derived software. * * Many thanks to David Glowacki (U. Wisconsin) for substantial * improvements, enhancements and bug fixes. */ import java.io.IOException; import nom.tam.util.BufferedDataInputStream; import nom.tam.util.BufferedDataOutputStream; import java.util.Date; /** This abstract class is the parent of all HDU types. * It provides basic functionality for an HDU. */ public abstract class BasicHDU { public static final int BITPIX_BYTE = 8; public static final int BITPIX_SHORT = 16; public static final int BITPIX_INT = 32; public static final int BITPIX_LONG = 64; public static final int BITPIX_FLOAT = -32; public static final int BITPIX_DOUBLE = -64; /** The associated header. */ Header myHeader = null; /** The associated data unit. */ Data myData = null; /** Create an HDU with the specified Header and an empty Data section * @param header the Header */ public BasicHDU(Header header) { myHeader = header; if (myHeader != null) { myHeader.unsetMark(); } } /** Create a Data object to correspond to the header description. * @return An unfilled Data object which can be used to read * in the data for this HDU. * @exception FitsException if the Data object could not be created * from this HDU's Header */ abstract Data manufactureData() throws FitsException; /** Skip the Data object immediately after the given Header object on * the given stream object. * @param stream the stream which contains the data. * @param Header template indicating length of Data section * @exception IOException if the Data object could not be skipped. */ public static void skipData(BufferedDataInputStream stream, Header hdr) throws IOException { stream.skipBytes(hdr.paddedDataSize()); } /** Skip the Data object for this HDU. * @param stream the stream which contains the data. * @exception IOException if the Data object could not be skipped. */ public void skipData(BufferedDataInputStream stream) throws IOException { skipData(stream, myHeader); } /** Read in the Data object for this HDU. * @param stream the stream from which the data is read. * @exception FitsException if the Data object could not be created * from this HDU's Header */ public void readData(BufferedDataInputStream stream) throws FitsException { myData = null; try { myData = manufactureData(); } finally { // if we can't build a Data object, skip this section if (myData == null) { try { skipData(stream, myHeader); } catch (Exception e) { } } } myData.read(stream); } /** Get the associated header */ public Header getHeader() { return myHeader; } /** Get the associated Data object*/ public Data getData() { return myData; } /** Get the total size in bytes of the HDU. * @return The size in bytes. */ public int getSize() { int size = 0; if (myHeader != null) { size += myHeader.headerSize(); } if (myData != null) { size += myData.getPaddedSize(); } return size; } /** Check that this is a valid header for the HDU. * @param header to validate. * @return <CODE>true</CODE> if this is a valid header. */ public static boolean isHeader(Header header) { return false; } /** Print out some information about this HDU. */ public abstract void info(); /** Check if a field is present and if so print it out. * @param The header keyword. * @param Was it found in the header? */ boolean checkField(String name) { String value = myHeader.getStringValue(name); if (value == null) { return false; } System.out.print(" "+name+"="+value+";"); return true; } /* Write out the HDU * @param stream The data stream to be written to. */ public void write(BufferedDataOutputStream stream) throws FitsException { if (myHeader != null) { myHeader.write(stream); } if (myData != null) { myData.write(stream); } try { stream.flush(); } catch (java.io.IOException e) { throw new FitsException("Error flushing at end of HDU: " + e.getMessage()); } } /** * Get the String value associated with <CODE>keyword</CODE>. * @param hdr the header piece of an HDU * @param keyword the FITS keyword * @return either <CODE>null</CODE> or a String with leading/trailing * blanks stripped. */ public String getTrimmedString(String keyword) { String s = myHeader.getStringValue(keyword); if (s != null) { s = s.trim(); } return s; } public int getBitPix() throws FitsException { int bitpix = myHeader.getIntValue("BITPIX", -1); switch (bitpix) { case BITPIX_BYTE: case BITPIX_SHORT: case BITPIX_INT: case BITPIX_FLOAT: case BITPIX_DOUBLE: break; default: throw new FitsException("Unknown BITPIX type " + bitpix); } return bitpix; } public int[] getAxes() throws FitsException { int nAxis = myHeader.getIntValue("NAXIS", 0); if (nAxis < 0) { throw new FitsException("Negative NAXIS value " + nAxis); } if (nAxis > 999) { throw new FitsException("NAXIS value " + nAxis + " too large"); } if (nAxis == 0) { return null; } int[] axes = new int[nAxis]; for (int i = 1; i <= nAxis; i++) { axes[nAxis - i] = myHeader.getIntValue("NAXIS" + i, 0); } return axes; } public int getParameterCount() { return myHeader.getIntValue("PCOUNT", 0); } public int getGroupCount() { return myHeader.getIntValue("GCOUNT", 1); } public double getBScale() { return myHeader.getDoubleValue("BSCALE", 1.0); } public double getBZero() { return myHeader.getDoubleValue("BZERO", 0.0); } public String getBUnit() { return getTrimmedString("BUNIT"); } public int getBlankValue() throws FitsException { if (!myHeader.containsKey("BLANK")) { throw new FitsException("BLANK undefined"); } return myHeader.getIntValue("BLANK"); } /** * Get the FITS file creation date as a <CODE>Date</CODE> object. * @return either <CODE>null</CODE> or a Date object */ public Date getCreationDate() { try { return new FitsDate(myHeader.getStringValue("DATE")).toDate(); } catch (FitsException e) { return null; } } /** * Get the FITS file observation date as a <CODE>Date</CODE> object. * @return either <CODE>null</CODE> or a Date object */ public Date getObservationDate() { try { return new FitsDate(myHeader.getStringValue("DATE-OBS")).toDate(); } catch (FitsException e) { return null; } } /** * Get the name of the organization which created this FITS file. * @return either <CODE>null</CODE> or a String object */ public String getOrigin() { return getTrimmedString("ORIGIN"); } /** * Get the name of the telescope which was used to acquire the data in * this FITS file. * @return either <CODE>null</CODE> or a String object */ public String getTelescope() { return getTrimmedString("TELESCOP"); } /** * Get the name of the instrument which was used to acquire the data in * this FITS file. * @return either <CODE>null</CODE> or a String object */ public String getInstrument() { return getTrimmedString("INSTRUME"); } /** * Get the name of the person who acquired the data in this FITS file. * @return either <CODE>null</CODE> or a String object */ public String getObserver() { return getTrimmedString("OBSERVER"); } /** * Get the name of the observed object in this FITS file. * @return either <CODE>null</CODE> or a String object */ public String getObject() { return getTrimmedString("OBJECT"); } /** * Get the equinox in years for the celestial coordinate system in which * positions given in either the header or data are expressed. * @return either <CODE>null</CODE> or a String object */ public double getEquinox() { return myHeader.getDoubleValue("EQUINOX", -1.0); } /** * Get the equinox in years for the celestial coordinate system in which * positions given in either the header or data are expressed. * @return either <CODE>null</CODE> or a String object * @deprecated Replaced by getEquinox * @see #getEquinox() */ public double getEpoch() { return myHeader.getDoubleValue("EPOCH", -1.0); } /** * Return the name of the person who compiled the information in * the data associated with this header. * @return either <CODE>null</CODE> or a String object */ public String getAuthor() { return getTrimmedString("AUTHOR"); } /** * Return the citation of a reference where the data associated with * this header are published. * @return either <CODE>null</CODE> or a String object */ public String getReference() { return getTrimmedString("REFERENC"); } /** * Return the minimum valid value in the array. * @return minimum value. */ public double getMaximumValue() { return myHeader.getDoubleValue("DATAMAX"); } /** * Return the minimum valid value in the array. * @return minimum value. */ public double getMinimumValue() { return myHeader.getDoubleValue("DATAMIN"); } }