View Javadoc
1   package nom.tam.fits;
2   
3   import java.io.PrintStream;
4   import java.util.logging.Level;
5   import java.util.logging.Logger;
6   
7   import nom.tam.fits.header.Standard;
8   import nom.tam.image.StandardImageTiler;
9   import nom.tam.util.ArrayFuncs;
10  
11  /*
12   * #%L
13   * nom.tam FITS library
14   * %%
15   * Copyright (C) 2004 - 2024 nom-tam-fits
16   * %%
17   * This is free and unencumbered software released into the public domain.
18   *
19   * Anyone is free to copy, modify, publish, use, compile, sell, or
20   * distribute this software, either in source code form or as a compiled
21   * binary, for any purpose, commercial or non-commercial, and by any
22   * means.
23   *
24   * In jurisdictions that recognize copyright laws, the author or authors
25   * of this software dedicate any and all copyright interest in the
26   * software to the public domain. We make this dedication for the benefit
27   * of the public at large and to the detriment of our heirs and
28   * successors. We intend this dedication to be an overt act of
29   * relinquishment in perpetuity of all present and future rights to this
30   * software under copyright law.
31   *
32   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
33   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
34   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
35   * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
36   * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
37   * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
38   * OTHER DEALINGS IN THE SOFTWARE.
39   * #L%
40   */
41  
42  import static nom.tam.fits.header.Standard.BITPIX;
43  import static nom.tam.fits.header.Standard.GROUPS;
44  import static nom.tam.fits.header.Standard.NAXIS;
45  import static nom.tam.fits.header.Standard.NAXISn;
46  import static nom.tam.fits.header.Standard.SIMPLE;
47  import static nom.tam.fits.header.Standard.XTENSION;
48  import static nom.tam.util.LoggerHelper.getLogger;
49  
50  /**
51   * Header/data unit for images. Image HDUs are suitable for storing monolithic regular numerical arrays in 1 to 255
52   * dimensions, such as a <code>double[]</code>, <code>float[][]</code>, or <code>short[][][]</code>. ((FITS supports up
53   * to 999 dimensions, but Java support maxes at at 255 -- however it's unlikely you'll find this to be a serious
54   * limitation.)
55   * 
56   * @see ImageData
57   */
58  @SuppressWarnings("deprecation")
59  public class ImageHDU extends BasicHDU<ImageData> {
60  
61      private static final Logger LOG = getLogger(ImageHDU.class);
62  
63      @Override
64      protected final String getCanonicalXtension() {
65          return Standard.XTENSION_IMAGE;
66      }
67  
68      /**
69       * @deprecated                          (<i>for internal use</i>) Use {@link ImageData#from(Object)} instead. Will
70       *                                          reduce visibility in the future
71       *
72       * @return                              Encapsulate an object as an ImageHDU.
73       *
74       * @param      o                        object to encapsulate
75       *
76       * @throws     FitsException            <i>does not actually throw this exception</i>
77       * @throws     IllegalArgumentException if the data is not a regular primitive numerical array suitable for an
78       *                                          image.
79       */
80      @Deprecated
81      public static ImageData encapsulate(Object o) throws IllegalArgumentException, FitsException {
82          return new ImageData(o);
83      }
84  
85      /**
86       * @deprecated   (<i>for internal use</i>) Will reduce visibility in the future
87       *
88       * @return       is this object can be described as a FITS image.
89       *
90       * @param      o The Object being tested.
91       */
92      @Deprecated
93      public static boolean isData(Object o) {
94          try {
95              ImageData.checkCompatible(o);
96          } catch (Exception e) {
97              return false;
98          }
99          return true;
100     }
101 
102     /**
103      * Check that this HDU has a valid header for this type.
104      *
105      * @deprecated     (<i>for internal use</i>) Will reduce visibility in the future
106      *
107      * @param      hdr header to check
108      *
109      * @return         <CODE>true</CODE> if this HDU has a valid header.
110      */
111     @Deprecated
112     public static boolean isHeader(Header hdr) {
113         boolean found = hdr.getBooleanValue(SIMPLE);
114         if (!found) {
115             String xtension = hdr.getStringValue(XTENSION);
116             xtension = xtension == null ? "" : xtension.trim();
117             if (Standard.XTENSION_IMAGE.equals(xtension) || "IUEIMAGE".equals(xtension)) {
118                 found = true;
119             }
120         }
121         if (!found) {
122             return false;
123         }
124         return !hdr.getBooleanValue(GROUPS);
125     }
126 
127     /**
128      * Prepares a data object into which the actual data can be read from an input subsequently or at a later time.
129      *
130      * @deprecated               (<i>for internal use</i>) Will reduce visibility in the future
131      *
132      * @param      hdr           The FITS header that describes the data
133      *
134      * @return                   A data object that support reading content from a stream.
135      *
136      * @throws     FitsException if the data could not be prepared to prescriotion.
137      */
138     @Deprecated
139     public static ImageData manufactureData(Header hdr) throws FitsException {
140         return new ImageData(hdr);
141     }
142 
143     /**
144      * Prepares a data object into which the actual data can be read from an input subsequently or at a later time.
145      *
146      * @deprecated               (<i>for internal use</i>) Will reduce visibility in the future
147      *
148      * @param      d             The FITS data content of this HDU
149      *
150      * @return                   A data object that support reading content from a stream.
151      *
152      * @throws     FitsException if the data could not be prepared to prescriotion.
153      */
154     @Deprecated
155     public static Header manufactureHeader(Data d) throws FitsException {
156         if (d == null) {
157             return null;
158         }
159 
160         Header h = new Header();
161         d.fillHeader(h);
162 
163         return h;
164     }
165 
166     /**
167      * Build an image HDU using the supplied data.
168      * 
169      * @deprecated   (<i>for internal use</i>) Its visibility should be reduced to package level in the future.
170      *
171      * @param      h the header for the image.
172      * @param      d the data used in the image.
173      */
174     public ImageHDU(Header h, ImageData d) {
175         super(h, d);
176     }
177 
178     /**
179      * Returns the class that can be used to divide this image into tiles that may be processed separately (and in
180      * parallel).
181      * 
182      * @return image tiler for this image instance.
183      * 
184      * @see    ImageData#getTiler()
185      */
186     public StandardImageTiler getTiler() {
187         return myData.getTiler();
188     }
189 
190     @Override
191     public void info(PrintStream stream) {
192         if (isHeader(myHeader)) {
193             stream.println("  Image");
194         } else {
195             stream.println("  Image (bad header)");
196         }
197 
198         stream.println("      Header Information:");
199         stream.println("         BITPIX=" + myHeader.getIntValue(BITPIX, -1));
200         int naxis = myHeader.getIntValue(NAXIS, -1);
201         stream.println("         NAXIS=" + naxis);
202         for (int i = 1; i <= naxis; i++) {
203             stream.println("         NAXIS" + i + "=" + myHeader.getIntValue(NAXISn.n(i), -1));
204         }
205 
206         stream.println("      Data information:");
207         try {
208             if (myData.getData() == null) {
209                 stream.println("        No Data");
210             } else {
211                 stream.println("         " + ArrayFuncs.arrayDescription(myData.getData()));
212             }
213         } catch (Exception e) {
214             LOG.log(Level.SEVERE, "Unable to get image data", e);
215             stream.println("      Unable to get data");
216         }
217     }
218 
219     /**
220      * Returns the name of the physical unit in which images are represented.
221      * 
222      * @return the standard name of the physical unit in which the image is expressed, e.g. <code>"Jy beam^{-1}"</code>.
223      */
224     @Override
225     public String getBUnit() {
226         return super.getBUnit();
227     }
228 
229     /**
230      * Returns the integer value that signifies blank (missing or <code>null</code>) data in an integer image.
231      *
232      * @return               the integer value used for identifying blank / missing data in integer images.
233      * 
234      * @throws FitsException if the header does not specify a blanking value or if it is not appropriate for the type of
235      *                           imge (that is not an integer type image)
236      */
237     @Override
238     public long getBlankValue() throws FitsException {
239         if (getBitpix().getHeaderValue() < 0) {
240             throw new FitsException("No integer blanking value in floating-point images.");
241         }
242         return super.getBlankValue();
243     }
244 
245     /**
246      * Returns the floating-point increment between adjacent integer values in the image. Strictly speaking, only
247      * integer-type images should define a quantization scaling, but there is no harm in having this value in
248      * floating-point images also -- which may be interpreted as a hint for quantization, perhaps.
249      * 
250      * @return the floating-point quantum that corresponds to the increment of 1 in the integer data representation.
251      * 
252      * @see    #getBZero()
253      */
254     @Override
255     public double getBScale() {
256         return super.getBScale();
257     }
258 
259     /**
260      * Returns the floating-point value that corresponds to an 0 integer value in the image. Strictly speaking, only
261      * integer-type images should define a quantization offset, but there is no harm in having this value in
262      * floating-point images also -- which may be interpreted as a hint for quantization, perhaps.
263      * 
264      * @return the floating point value that correspond to the integer 0 in the image data.
265      * 
266      * @see    #getBScale()
267      */
268     @Override
269     public double getBZero() {
270         return super.getBZero();
271     }
272 
273 }