001 /* @(#)FitsRGroup.java $Revision: 1.1 $ $Date: 2002/05/06 12:41:34 $
002 *
003 * Copyright (C) 2000 European Southern Observatory
004 * License: GNU General Public License version 2 or later
005 */
006 package org.eso.fits;
007
008 import java.lang.*;
009 import java.io.*;
010
011 /** FitsRGroup class represents a FITS data matrix in the Random Group
012 * format.
013 *
014 * @version $Revision: 1.1 $ $Date: 2002/05/06 12:41:34 $
015 * @author P.Grosbol, DMD/ESO, <pgrosbol@eso.org>
016 */
017 public class FitsRGroup extends FitsData {
018
019 private int noValues;
020 private int dataFormat = Fits.FLOAT;
021 private int bytesPerData = 4;
022 private boolean scaling = false;
023 private double zero = 0.0;
024 private double scale = 1.0;
025 private FitsWCS wcs;
026
027 /** Constructor for FitsRGroup class given a FITS prime matrix or
028 * an image extension header with associated data unit as a file.
029 *
030 * @param header FitsHeader object with the image header
031 * @param file RandomAccess file positioned at the start of the
032 * associated data unit
033 * @param sflag Flag for storing data matrix internally
034 * @exception FitsException */
035 public FitsRGroup(FitsHeader header, DataInput file, boolean sflag)
036 throws FitsException {
037 super(header, file, sflag);
038
039 if (type != Fits.RGROUP) {
040 throw new FitsException("Wrong header type",
041 FitsException.HEADER);
042 }
043
044 int nax = naxis.length;
045
046 FitsKeyword kw = header.getKeyword("BITPIX");
047 if ((kw == null) || (kw.getType() != FitsKeyword.INTEGER)) {
048 throw new FitsException("Invalid or missing BITPIX",
049 FitsException.HEADER);
050 }
051
052 dataFormat = kw.getInt();
053 bytesPerData = Math.abs(dataFormat)/8;
054 noValues = (int) (size / bytesPerData);
055
056 wcs = new FitsWCS(header);
057
058 kw = header.getKeyword("BSCALE"); // check if scale is given
059 if (kw!=null) {
060 scale = kw.getReal();
061 if (scale != 1.0) {
062 scaling = true;
063 }
064 }
065
066 kw = header.getKeyword("BZERO"); // check if zero point is given
067 if (kw!=null) {
068 zero = kw.getReal();
069 if (zero != 0.0) {
070 scaling = true;
071 }
072 }
073 }
074
075 /** Create and return a minimum FITS header for data Matrix.
076 */
077 public FitsHeader getHeader() {
078 FitsHeader hdr = new FitsHeader();
079
080 hdr.addKeyword(new FitsKeyword("SIMPLE", true,
081 "Standard FITS format; NOST 100-2.0"));
082 hdr.addKeyword(new FitsKeyword("BITPIX", bitpix,
083 "No. of bits per pixel"));
084 hdr.addKeyword(new FitsKeyword("NAXIS", naxis.length+1,
085 "No. of axes in image"));
086 hdr.addKeyword(new FitsKeyword("NAXIS1",0,"Random Groups convension"));
087 for (int n=2; n<=naxis.length+1; n++) {
088 hdr.addKeyword(new FitsKeyword("NAXIS"+n, naxis[n-2],
089 "No. of pixels"));
090 }
091 hdr.addKeyword(new FitsKeyword("PCOUNT", noParm, "Parameter count"));
092 hdr.addKeyword(new FitsKeyword("GCOUNT", noGroup, "Group count"));
093 hdr.addKeyword(new FitsKeyword("GROUPS", true,
094 "Random Groups format"));
095
096
097 return hdr;
098 }
099
100 /** Gets set of data points from the matrix as a short values.
101 * Only FITS file with BITPIX 8, 16 and 32 are read.
102 *
103 * @param offset pixel offset within hte data matrix
104 * @param size no. of pixel values to be read
105 * @param data array which will hold the return values.
106 * If null an array of size is created.
107 * @return data[] array updated with pixel values
108 * @exception FitsException */
109 public short[] getShortValues(int offset, int size, short data[])
110 throws FitsException {
111
112 if ((offset<0) || (size<1)) return data;
113 if (noValues < offset+size) size = (int) (noValues - offset);
114 if ((data == null) || (data.length<size)) data = new short[size];
115
116 int n = 0;
117 DataInputStream dis = getStream(offset, size);
118 try {
119 switch (dataFormat) {
120 case Fits.BYTE:
121 while (n<size) data[n++] = (short) dis.readUnsignedByte();
122 break;
123 case Fits.SHORT:
124 while (n<size) data[n++] = dis.readShort();
125 break;
126 case Fits.INT:
127 while (n<size) data[n++] = (short) dis.readInt();
128 break;
129 case Fits.FLOAT:
130 case Fits.DOUBLE:
131 default: return data;
132 }
133 } catch (IOException e) {
134 throw new FitsException("Cannot convert data", FitsException.DATA);
135 }
136
137 if (scaling) {
138 for (int i=0; i<n; i++) data[i] = (short) (scale*data[i]+zero);
139 }
140
141 return data;
142 }
143
144 /** Gets set of data points from the matrix as a int values.
145 * Only FITS file with BITPIX 8, 16 and 32 are read.
146 *
147 * @param offset pixel offset within hte data matrix
148 * @param size no. of pixel values to be read
149 * @param data array which will hold the return values.
150 * If null an array of size is created.
151 * @return data[] array updated with pixel values
152 * @exception FitsException */
153 public int[] getFloatValues(int offset, int size, int data[])
154 throws FitsException {
155
156 if ((offset<0) || (size<1)) return data;
157 if (noValues < offset+size) size = (int) (noValues - offset);
158 if ((data == null) || (data.length<size)) data = new int[size];
159
160 int n = 0;
161 DataInputStream dis = getStream(offset, size);
162 try {
163 switch (dataFormat) {
164 case Fits.BYTE:
165 while (n<size) data[n++] = (int) dis.readUnsignedByte();
166 break;
167 case Fits.SHORT:
168 while (n<size) data[n++] = (int) dis.readShort();
169 break;
170 case Fits.INT:
171 while (n<size) data[n++] = dis.readInt();
172 break;
173 case Fits.FLOAT:
174 case Fits.DOUBLE:
175 default: return data;
176 }
177 } catch (IOException e) {
178 throw new FitsException("Cannot convert data", FitsException.DATA);
179 }
180
181 if (scaling) {
182 for (int i=0; i<n; i++) data[i] = (int) (scale*data[i]+zero);
183 }
184
185 return data;
186 }
187
188 /** Read set of data values from the matrix as a float array. The
189 * values are returned as a float array.
190 *
191 * @param offset pixel offset within hte data matrix
192 * @param size no. of pixel values to be read
193 * @param data array which will hold the return values.
194 * If null an array of size is created.
195 * @return data[] array updated with pixel values
196 * @exception FitsException */
197 public float[] getFloatValues(int offset, int size, float data[])
198 throws FitsException {
199
200 if ((offset<0) || (size<1)) return data;
201 if (noValues < offset+size) size = (int) (noValues - offset);
202 if ((data == null) || (data.length<size)) data = new float[size];
203
204 int n = 0;
205 DataInputStream dis = getStream(offset, size);
206 try {
207 switch (dataFormat) {
208 case Fits.BYTE:
209 while (n<size) data[n++] = (float) dis.readUnsignedByte();
210 break;
211 case Fits.SHORT:
212 while (n<size) data[n++] = (float) dis.readShort();
213 break;
214 case Fits.INT:
215 while (n<size) data[n++] = (float) dis.readInt();
216 break;
217 case Fits.FLOAT:
218 while (n<size) data[n++] = dis.readFloat();
219 break;
220 case Fits.DOUBLE:
221 while (n<size) data[n++] = (float) dis.readDouble();
222 break;
223 default: return data;
224 }
225 } catch (IOException e) {
226 throw new FitsException("Cannot convert data", FitsException.DATA);
227 }
228
229 if (scaling) {
230 for (int i=0; i<n; i++) data[i] = (float) (scale*data[i]+zero);
231 }
232
233 return data;
234 }
235
236 private DataInputStream getStream(int offset, int size)
237 throws FitsException {
238 DataInputStream di;
239 try {
240 dataFile.seek(dataOffset+offset*bytesPerData);
241 if (noValues < offset + size) {
242 size = (int) (noValues - offset);
243 }
244 byte[] dbuf = new byte[size*bytesPerData];
245 dataFile.read(dbuf);
246 di = new DataInputStream(new ByteArrayInputStream(dbuf));
247 } catch (IOException e) {
248 throw new FitsException("Cannot read data", FitsException.DATA);
249 }
250 return di;
251 }
252
253
254 /** Gets the total number of data values in the data matrix. */
255 public int getNoValues(){
256 return noValues;
257 }
258
259 /** Gets reference pixel for the axes (see CRPIXn). */
260 public double[] getCrpix(){
261 return wcs.crpix;
262 }
263
264 /** Gets coordinate value for the reference pixel of the axes
265 * (see CRVALn). */
266 public double[] getCrval(){
267 return wcs.crval;
268 }
269
270 /** Gets step size for the axes (see CDELTn). */
271 public double[] getCdelt(){
272 return wcs.cdelt;
273 }
274
275 /** Gets the WCS object for the image. */
276 public FitsWCS getWCS(){
277 return wcs;
278 }
279
280 /** Compute World Coordinates from pixel coordinates.
281 *
282 * @param pix Array with pixel coordinates
283 */
284 public double[] toWCS(double[] pix) {
285 return wcs.toWCS(pix);
286 }
287
288 /** Compute pixel coordinates from a set of World Coordinates.
289 *
290 * @param wc Array with World Coordinates
291 */
292 public double[] toPixel(double[] wc) {
293 return wcs.toPixel(wc);
294 }
295 }
296
297