/* @(#)FitsHDUnit.java $Revision: 1.8 $ $Date: 2004/01/12 13:13:23 $ * * Copyright (C) 202 European Southern Observatory * License: GNU General Public License version 2 or later */ package fr.unistra.pelican.util.jFits; import java.io.*; /** FitsData class represents a FITS data unit * * @version $Revision: 1.8 $ $Date: 2004/01/12 13:13:23 $ * @author P.Grosbol, ESO, <pgrosbol@eso.org> */ public class FitsHDUnit { private FitsHeader header; private FitsData data; private boolean changeHeader = false; private long headerOffset = 0; private RandomAccessFile headerFile = null; /** Constructor for FitsHDUnit class given a FITS stream and a internal * storage flag. * * @param file DataInput file positioned at the start of the * header/data unit * @param sflag Flag for storing data matrix internally * @exception FitsException */ public FitsHDUnit(DataInput file, boolean sflag) throws FitsException { if (file instanceof RandomAccessFile) { headerFile = (RandomAccessFile) file; try { headerOffset = headerFile.getFilePointer(); } catch (IOException e) { throw new FitsException("Cannot read header offset", FitsException.FILE); } } header = new FitsHeader(file); int type = header.getType(); switch (type) { case Fits.IMAGE: data = new FitsMatrix(header, file, sflag); break; case Fits.BTABLE: case Fits.ATABLE: data = new FitsTable(header, file, sflag); break; case Fits.RGROUP: data = new FitsRGroup(header, file, sflag); break; } changeHeader = false; } /** Constructor from individual header and data objects. * * @param header new FitsHeader object to used * @param data new FitsData object associated to header * @exception FitsException */ public FitsHDUnit(FitsHeader header, FitsData data) throws FitsException { this.header = header; this.data = data; changeHeader = true; } /** Get the type of Header/Data unit as indicated by its header. */ public int getType(){ return header.getType(); } /** Check if HD unit can be save to FITS file in place that is * a FITS file exists and has space enough. */ public boolean canSave() { if (changeHeader || (headerFile==null)) { return false; } int nfill = header.getHeaderSpace() - header.getNoKeywords() - 1; if (nfill<0) { return false; } return true; } /** Save changes of a HD unit to FITS file. The HDunit must have * been created from a read/write RandomAccess disk file. * There are no check for the consistence of Header and Data. * * @exception IOException, FitsException */ protected void saveFile(RandomAccessFile file) throws IOException, FitsException { if (changeHeader) { throw new FitsException("HD unit modified", FitsException.FILE); } if (headerFile == null) { throw new FitsException("No header file", FitsException.FILE); } int nfill = header.getHeaderSpace() - header.getNoKeywords() - 1; if (nfill<0) { throw new FitsException("No space in FITS header", FitsException.NOHEADERSPACE); } file.seek(headerOffset); file.write((header.toString()).getBytes()); // Write the header while (0<nfill--) file.write(Fits.BLANK_CARD.getBytes()); file.write(Fits.END_CARD.getBytes()); } /** Write FITS header/Data unit to a DataOutput stream. * * @param file DataOutput object to which to write * @exception IOException, FitsException */ public void writeFile(DataOutput file) throws IOException, FitsException { int nokw = header.getNoKeywords(); if (nokw<2) { throw new FitsException("Bad FITS header",FitsException.HEADER); } file.write((header.toString()).getBytes()); // Write the header // Add BLANK-cards and the final END-card to fill the FITS record int nfill = Fits.NOCARDS*(nokw/Fits.NOCARDS + 1) - nokw - 1; while (0<nfill--) file.write(Fits.BLANK_CARD.getBytes()); file.write(Fits.END_CARD.getBytes()); data.writeFile(file); } /** Remove all references to the DataInput file from data unit */ public void closeFile() { headerFile = null; data.closeFile(); } /** Return the FitsData object in the Header/Data unit */ public FitsData getData(){ return data; } /** Return the header object in the Header/Data unit */ public FitsHeader getHeader(){ return header; } }