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