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  import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
51  
52  /**
53   * Header/data unit for images. Image HDUs are suitable for storing monolithic regular numerical arrays in 1 to 255
54   * dimensions, such as a <code>double[]</code>, <code>float[][]</code>, or <code>short[][][]</code>. ((FITS supports up
55   * to 999 dimensions, but Java support maxes at at 255 -- however it's unlikely you'll find this to be a serious
56   * limitation.)
57   * 
58   * @see ImageData
59   */
60  @SuppressWarnings("deprecation")
61  public class ImageHDU extends BasicHDU<ImageData> {
62  
63      private static final Logger LOG = getLogger(ImageHDU.class);
64  
65      @Override
66      protected final String getCanonicalXtension() {
67          return Standard.XTENSION_IMAGE;
68      }
69  
70      /**
71       * @deprecated                          (<i>for internal use</i>) Use {@link ImageData#from(Object)} instead. Will
72       *                                          reduce visibility in the future
73       *
74       * @return                              Encapsulate an object as an ImageHDU.
75       *
76       * @param      o                        object to encapsulate
77       *
78       * @throws     FitsException            <i>does not actually throw this exception</i>
79       * @throws     IllegalArgumentException if the data is not a regular primitive numerical array suitable for an
80       *                                          image.
81       */
82      @Deprecated
83      public static ImageData encapsulate(Object o) throws IllegalArgumentException, FitsException {
84          return new ImageData(o);
85      }
86  
87      /**
88       * @deprecated   (<i>for internal use</i>) Will reduce visibility in the future
89       *
90       * @return       is this object can be described as a FITS image.
91       *
92       * @param      o The Object being tested.
93       */
94      @SuppressFBWarnings(value = "HSM_HIDING_METHOD", justification = "deprecated existing method, kept for compatibility")
95      @Deprecated
96      public static boolean isData(Object o) {
97          try {
98              ImageData.checkCompatible(o);
99          } catch (Exception e) {
100             return false;
101         }
102         return true;
103     }
104 
105     /**
106      * Check that this HDU has a valid header for this type.
107      *
108      * @deprecated     (<i>for internal use</i>) Will reduce visibility in the future
109      *
110      * @param      hdr header to check
111      *
112      * @return         <CODE>true</CODE> if this HDU has a valid header.
113      */
114     @SuppressFBWarnings(value = "HSM_HIDING_METHOD", justification = "deprecated existing method, kept for compatibility")
115     @Deprecated
116     public static boolean isHeader(Header hdr) {
117         boolean found = hdr.getBooleanValue(SIMPLE);
118         if (!found) {
119             String xtension = hdr.getStringValue(XTENSION);
120             xtension = xtension == null ? "" : xtension.trim();
121             if (Standard.XTENSION_IMAGE.equals(xtension) || "IUEIMAGE".equals(xtension)) {
122                 found = true;
123             }
124         }
125         if (!found) {
126             return false;
127         }
128         return !hdr.getBooleanValue(GROUPS);
129     }
130 
131     /**
132      * Prepares a data object into which the actual data can be read from an input subsequently or at a later time.
133      *
134      * @deprecated               (<i>for internal use</i>) Will reduce visibility in the future
135      *
136      * @param      hdr           The FITS header that describes the data
137      *
138      * @return                   A data object that support reading content from a stream.
139      *
140      * @throws     FitsException if the data could not be prepared to prescriotion.
141      */
142     @Deprecated
143     public static ImageData manufactureData(Header hdr) throws FitsException {
144         return new ImageData(hdr);
145     }
146 
147     /**
148      * Prepares a data object into which the actual data can be read from an input subsequently or at a later time.
149      *
150      * @deprecated               (<i>for internal use</i>) Will reduce visibility in the future
151      *
152      * @param      d             The FITS data content of this HDU
153      *
154      * @return                   A data object that support reading content from a stream.
155      *
156      * @throws     FitsException if the data could not be prepared to prescriotion.
157      */
158     @Deprecated
159     public static Header manufactureHeader(Data d) throws FitsException {
160         if (d == null) {
161             return null;
162         }
163 
164         Header h = new Header();
165         d.fillHeader(h);
166 
167         return h;
168     }
169 
170     /**
171      * Build an image HDU using the supplied data.
172      * 
173      * @deprecated   (<i>for internal use</i>) Its visibility should be reduced to package level in the future.
174      *
175      * @param      h the header for the image.
176      * @param      d the data used in the image.
177      */
178     public ImageHDU(Header h, ImageData d) {
179         super(h, d);
180     }
181 
182     /**
183      * Returns the class that can be used to divide this image into tiles that may be processed separately (and in
184      * parallel).
185      * 
186      * @return image tiler for this image instance.
187      * 
188      * @see    ImageData#getTiler()
189      */
190     public StandardImageTiler getTiler() {
191         return myData.getTiler();
192     }
193 
194     @Override
195     public void info(PrintStream stream) {
196         if (isHeader(myHeader)) {
197             stream.println("  Image");
198         } else {
199             stream.println("  Image (bad header)");
200         }
201 
202         stream.println("      Header Information:");
203         stream.println("         BITPIX=" + myHeader.getIntValue(BITPIX, -1));
204         int naxis = myHeader.getIntValue(NAXIS, -1);
205         stream.println("         NAXIS=" + naxis);
206         for (int i = 1; i <= naxis; i++) {
207             stream.println("         NAXIS" + i + "=" + myHeader.getIntValue(NAXISn.n(i), -1));
208         }
209 
210         stream.println("      Data information:");
211         try {
212             if (myData.getData() == null) {
213                 stream.println("        No Data");
214             } else {
215                 stream.println("         " + ArrayFuncs.arrayDescription(myData.getData()));
216             }
217         } catch (Exception e) {
218             LOG.log(Level.SEVERE, "Unable to get image data", e);
219             stream.println("      Unable to get data");
220         }
221     }
222 
223     /**
224      * Returns the name of the physical unit in which images are represented.
225      * 
226      * @return the standard name of the physical unit in which the image is expressed, e.g. <code>"Jy beam^{-1}"</code>.
227      */
228     @Override
229     public String getBUnit() {
230         return super.getBUnit();
231     }
232 
233     /**
234      * Returns the integer value that signifies blank (missing or <code>null</code>) data in an integer image.
235      *
236      * @return               the integer value used for identifying blank / missing data in integer images.
237      * 
238      * @throws FitsException if the header does not specify a blanking value or if it is not appropriate for the type of
239      *                           imge (that is not an integer type image)
240      */
241     @Override
242     public long getBlankValue() throws FitsException {
243         if (getBitpix().getHeaderValue() < 0) {
244             throw new FitsException("No integer blanking value in floating-point images.");
245         }
246         return super.getBlankValue();
247     }
248 
249     /**
250      * Returns the floating-point increment between adjacent integer values in the image. Strictly speaking, only
251      * integer-type images should define a quantization scaling, but there is no harm in having this value in
252      * floating-point images also -- which may be interpreted as a hint for quantization, perhaps.
253      * 
254      * @return the floating-point quantum that corresponds to the increment of 1 in the integer data representation.
255      * 
256      * @see    #getBZero()
257      */
258     @Override
259     public double getBScale() {
260         return super.getBScale();
261     }
262 
263     /**
264      * Returns the floating-point value that corresponds to an 0 integer value in the image. Strictly speaking, only
265      * integer-type images should define a quantization offset, but there is no harm in having this value in
266      * floating-point images also -- which may be interpreted as a hint for quantization, perhaps.
267      * 
268      * @return the floating point value that correspond to the integer 0 in the image data.
269      * 
270      * @see    #getBScale()
271      */
272     @Override
273     public double getBZero() {
274         return super.getBZero();
275     }
276 
277 }