View Javadoc
1   package nom.tam.image.compression.hdu;
2   
3   import java.io.File;
4   
5   /*
6    * #%L
7    * nom.tam FITS library
8    * %%
9    * Copyright (C) 1996 - 2024 nom-tam-fits
10   * %%
11   * This is free and unencumbered software released into the public domain.
12   *
13   * Anyone is free to copy, modify, publish, use, compile, sell, or
14   * distribute this software, either in source code form or as a compiled
15   * binary, for any purpose, commercial or non-commercial, and by any
16   * means.
17   *
18   * In jurisdictions that recognize copyright laws, the author or authors
19   * of this software dedicate any and all copyright interest in the
20   * software to the public domain. We make this dedication for the benefit
21   * of the public at large and to the detriment of our heirs and
22   * successors. We intend this dedication to be an overt act of
23   * relinquishment in perpetuity of all present and future rights to this
24   * software under copyright law.
25   *
26   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
29   * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
30   * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
31   * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
32   * OTHER DEALINGS IN THE SOFTWARE.
33   * #L%
34   */
35  
36  import java.io.IOException;
37  import java.lang.reflect.Array;
38  import java.util.Arrays;
39  
40  import org.junit.jupiter.api.Assertions;
41  import org.junit.jupiter.api.Disabled;
42  import org.junit.jupiter.api.Test;
43  
44  import nom.tam.fits.BinaryTableHDU;
45  import nom.tam.fits.Fits;
46  import nom.tam.fits.FitsException;
47  import nom.tam.fits.HeaderCard;
48  import nom.tam.fits.header.Compression;
49  import nom.tam.fits.util.BlackBoxImages;
50  import nom.tam.util.Cursor;
51  import nom.tam.util.SafeClose;
52  
53  @SuppressWarnings({"javadoc", "deprecation"})
54  public class CompressedTableBlackBoxTest {
55  
56      @Test
57      public void testUncompress_mddtsapcln() throws Exception {
58          uncompressTableAndAssert("bintable/mddtsapcln.fits.fz", "bintable/mddtsapcln.fits");
59      }
60  
61      private void compressThenUncompressTableAndAssert(String originalFileName) throws FitsException, IOException {
62          compressThenUncompressTableAndAssert(originalFileName, Compression.ZCMPTYPE_GZIP_1);
63          compressThenUncompressTableAndAssert(originalFileName, Compression.ZCMPTYPE_GZIP_2);
64          // compressThenUncompressTableAndAssert(originalFileName, Compression.ZCMPTYPE_RICE_1);
65          compressThenUncompressTableAndAssert(originalFileName, Compression.ZCMPTYPE_NOCOMPRESS);
66      }
67  
68      private void compressIntThenUncompressTableAndAssert(String originalFileName) throws FitsException, IOException {
69          compressThenUncompressTableAndAssert(originalFileName, Compression.ZCMPTYPE_GZIP_1);
70          compressThenUncompressTableAndAssert(originalFileName, Compression.ZCMPTYPE_GZIP_2);
71          compressThenUncompressTableAndAssert(originalFileName, Compression.ZCMPTYPE_RICE_1);
72          compressThenUncompressTableAndAssert(originalFileName, Compression.ZCMPTYPE_NOCOMPRESS);
73      }
74  
75      private void compressThenUncompressTableAndAssert(String originalFileName, String algo)
76              throws FitsException, IOException {
77          String tableOrgFile = BlackBoxImages.getBlackBoxImage(originalFileName);
78  
79          String[] algos = new String[100];
80          Arrays.fill(algos, algo);
81  
82          File file = new File("target/" + originalFileName + ".fz");
83          file.getParentFile().mkdirs();
84  
85          try (Fits fitsCompressed = new Fits(); Fits fitsOrg = new Fits(tableOrgFile)) {
86              CompressedTableHDU cHDU = CompressedTableHDU.fromBinaryTableHDU((BinaryTableHDU) fitsOrg.getHDU(1), 0, algos)//
87                      .compress();
88  
89              for (int col = 0; col < cHDU.getNCols(); col++) {
90                  Assertions.assertEquals(algo, cHDU.getHeader().getStringValue(Compression.ZCTYPn.n(col + 1)));
91              }
92  
93              fitsCompressed.addHDU(cHDU);
94  
95              fitsCompressed.write(file);
96              fitsCompressed.close();
97              fitsOrg.close();
98          }
99  
100         uncompressTableAndAssert(file.getAbsolutePath(), originalFileName);
101     }
102 
103     private void uncompressTableAndAssert(String compressedfileName, String originalFileName)
104             throws FitsException, IOException {
105         String tableFile;
106         if (new File(compressedfileName).exists()) {
107             tableFile = compressedfileName;
108         } else {
109             tableFile = BlackBoxImages.getBlackBoxImage(compressedfileName);
110         }
111         Fits fitsComp = null;
112         String tableOrgFile = BlackBoxImages.getBlackBoxImage(originalFileName);
113         Fits fitsOrg = null;
114         try {
115             fitsComp = new Fits(tableFile);
116             fitsComp.readHDU(); // skip image
117             CompressedTableHDU compressedTable = (CompressedTableHDU) fitsComp.readHDU();
118             BinaryTableHDU uncompressedTable = compressedTable.asBinaryTableHDU();
119             fitsOrg = new Fits(tableOrgFile);
120             fitsOrg.readHDU(); // skip image
121             BinaryTableHDU orgTable = compressedTable.asBinaryTableHDU();
122 
123             assertEquals(orgTable, uncompressedTable);
124 
125             fitsOrg.close();
126         } finally {
127             SafeClose.close(fitsComp);
128             SafeClose.close(fitsOrg);
129         }
130     }
131 
132     private void assertEquals(BinaryTableHDU orgTable, BinaryTableHDU testTable) throws FitsException {
133         int numberOfCards = orgTable.getHeader().getNumberOfCards();
134         // Assertions.assertEquals(numberOfCards, testTable.getHeader().getNumberOfCards());
135         Cursor<String, HeaderCard> orgIterator = orgTable.getHeader().iterator();
136         for (int index = 0; index < numberOfCards; index++) {
137             HeaderCard orgCard = orgIterator.next();
138             HeaderCard testCard = testTable.getHeader().findCard(orgCard.getKey());
139             Assertions.assertEquals(orgCard.getValue(), testCard.getValue(), "header " + orgCard.getKey());
140         }
141         for (int column = 0; column < orgTable.getNCols(); column++) {
142             for (int row = 0; row < orgTable.getNRows(); row++) {
143                 Object orgValue = orgTable.getElement(row, column);
144                 Object testValue = testTable.getElement(row, column);
145                 assertValues("col=" + column + ", row=" + row, orgValue, testValue);
146             }
147         }
148     }
149 
150     private void assertValues(String label, Object orgValue, Object testValue) {
151         if (orgValue.getClass().isArray()) {
152             int arraySize = Array.getLength(orgValue);
153             for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) {
154                 Object orgValueElement = Array.get(orgValue, arrayIndex);
155                 Object testValueElement = Array.get(testValue, arrayIndex);
156                 assertValues(label + ":" + arrayIndex, orgValueElement, testValueElement);
157             }
158         } else {
159             Assertions.assertEquals(orgValue, testValue);
160         }
161     }
162 
163     @Test
164     public void testUncompress_swp06542llg() throws FitsException, IOException {
165         uncompressTableAndAssert("bintable/swp06542llg.fits.fz", "bintable/swp06542llg.fits");
166     }
167 
168     @Test
169     public void testUncompress_testdata() throws FitsException, IOException {
170         uncompressTableAndAssert("bintable/testdata.fits.fz", "bintable/testdata.fits");
171     }
172 
173     @Test
174     @Disabled // TODO also cfitsio can not uncompress this, mail to bill 22.7.2016
175     public void testUncompress_tst0010() throws FitsException, IOException {
176         uncompressTableAndAssert("bintable/tst0010.fits.fz", "bintable/tst0010.fits");
177     }
178 
179     @Test
180     @Disabled // TODO also cfitsio can not uncompress this, mail to bill 22.7.2016
181     public void testUncompress_tst0012() throws FitsException, IOException {
182         uncompressTableAndAssert("bintable/tst0012.fits.fz", "bintable/tst0012.fits");
183     }
184 
185     @Test
186     public void testUncompress_tst0014() throws FitsException, IOException {
187         uncompressTableAndAssert("bintable/tst0014.fits.fz", "bintable/tst0014.fits");
188     }
189 
190     // TODO add fpack files to blackbox images, and enable tests once fpack fixes its
191     // critical bugs.
192     // @Test
193     // public void testUncompress_vtab_p() throws FitsException, IOException {
194     // uncompressTableAndAssert("bintable/vtab.p.fits.fz", "bintable/vtab.p.fits");
195     // }
196     //
197     // @Test
198     // public void testUncompress_vtab_q() throws FitsException, IOException {
199     // uncompressTableAndAssert("bintable/vtab.q.fits.fz", "bintable/vtab.q.fits");
200     // }
201 
202     @Test
203     public void testCompressAndUncompress_dddtsuvdata() throws FitsException, IOException {
204         compressThenUncompressTableAndAssert("bintable/dddtsuvdata.fits");
205     }
206 
207     @Test
208     public void testCompressAndUncompress_mddtsapcln() throws FitsException, IOException {
209         compressThenUncompressTableAndAssert("bintable/mddtsapcln.fits");
210     }
211 
212     @Test
213     public void testCompressAndUncompress_swp06542llg() throws FitsException, IOException {
214         compressThenUncompressTableAndAssert("bintable/swp06542llg.fits");
215     }
216 
217     @Test
218     public void testCompressAndUncompress_testdata() throws FitsException, IOException {
219         compressThenUncompressTableAndAssert("bintable/testdata.fits");
220     }
221 
222     @Test
223     public void testCompressAndUncompress_tst0010() throws FitsException, IOException {
224         compressThenUncompressTableAndAssert("bintable/tst0010.fits");
225     }
226 
227     @Test
228     public void testCompressAndUncompress_tst0012() throws FitsException, IOException {
229         compressThenUncompressTableAndAssert("bintable/tst0012.fits");
230     }
231 
232     @Test
233     public void testCompressAndUncompress_tst0014() throws FitsException, IOException {
234         compressThenUncompressTableAndAssert("bintable/tst0014.fits");
235     }
236 
237     @Test
238     public void testCompressAndUncompress_vtab_p() throws FitsException, IOException {
239         compressIntThenUncompressTableAndAssert("bintable/vtab.p.fits");
240     }
241 
242     @Test
243     public void testCompressAndUncompress_vtab_q() throws FitsException, IOException {
244         compressIntThenUncompressTableAndAssert("bintable/vtab.q.fits");
245     }
246 
247     @Test
248     public void test_vtab_q_reversed() throws Exception {
249         try {
250             CompressedTableHDU.useOldStandardVLAIndexing(true);
251             Assertions.assertThrows(Exception.class, () -> compressIntThenUncompressTableAndAssert("bintable/vtab.q.fits"));
252         } finally {
253             CompressedTableHDU.useOldStandardVLAIndexing(false);
254         }
255     }
256 
257     @Test
258     public void test_vtab_p_reversed() throws Exception {
259         try {
260             CompressedTableHDU.useOldStandardVLAIndexing(true);
261             Assertions.assertThrows(Exception.class, () -> compressIntThenUncompressTableAndAssert("bintable/vtab.p.fits"));
262         } finally {
263             CompressedTableHDU.useOldStandardVLAIndexing(false);
264         }
265     }
266 }