View Javadoc
1   package nom.tam.fits;
2   
3   import nom.tam.util.ComplexValue;
4   
5   /*
6    * #%L
7    * nom.tam FITS library
8    * %%
9    * Copyright (C) 2004 - 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  /**
37   * <p>
38   * Interface for accessing binary and ASCII table data.
39   * </p>
40   * <p>
41   * Note, that this interface is the big sister {@link nom.tam.util.DataTable}, with nearly identical method signstures.
42   * But there are differences too, such as the type of argument of setting row data, and when and what excpetions are
43   * thrown. This one also has includes additional methods for table manipulation. Overall it would have been a more
44   * prudent design to consolidate the two interfaces but this is what we have so we stick to it. However, mabe this is
45   * something an upcoming major release may address...
46   * </p>
47   * 
48   * @see nom.tam.util.DataTable
49   */
50  
51  public interface TableData {
52  
53      /**
54       * Add a column to the table, without updating the header of an encompassing HDU. You should not use this method on
55       * tables already in an HDU, since it will not update the HDUs headers. Instead you can either use
56       * {@link TableHDU#addColumn(Object)} or else create a new HDU for the table once the editing is copmleted -- adding
57       * or migrating any custom header entries as necessary after.
58       * 
59       * @param  newCol        the new column information. it should be either a primitive array, in which each element
60       *                           stores a scalar value for every row, or else an <code>Object[]</code> where type of all
61       *                           of the constituents is identical. Multidimensional data should have the same layout in
62       *                           each row, but varied length one-dimensional arrays are OK. The arrat's length must
63       *                           match the number of rows already contained in the table, unless the table is still
64       *                           empty.
65       * 
66       * @return               the number of columns in the adapted table
67       * 
68       * @see                  TableHDU#addColumn(Object)
69       * @see                  #deleteColumns(int, int)
70       * @see                  #addRow(Object[])
71       * 
72       * @throws FitsException if the operation failed
73       */
74      int addColumn(Object newCol) throws FitsException;
75  
76      /**
77       * Add a row at the end of the table without updating the header of an encompassing HDU. You should not use this
78       * method on tables already in an HDU, since it will not update the HDUs headers. Instead you can use
79       * {@link TableHDU#addRow(Object[])} or else create a new HDU for the table once the editing is completed -- adding
80       * or migrating any custom header entries as necessary after.
81       * 
82       * @param  newRow        An array of elements to be added. Each element of o should be an array of primitives or a
83       *                           String.
84       * 
85       * @throws FitsException if the operation failed
86       * 
87       * @return               the number of rows in the adapted table
88       * 
89       * @see                  TableHDU#addColumn(Object)
90       * @see                  #setRowEntries(int, Object...)
91       * @see                  #deleteRows(int, int)
92       * @see                  #addColumn(Object)
93       */
94      int addRow(Object[] newRow) throws FitsException;
95  
96      /**
97       * Like {@link #addRow(Object[])}, but with a vararg list of row entries.
98       * 
99       * @param  entries       A vararg list of elements to be added. Each element of o should be an array of primitives
100      *                           or a String.
101      * 
102      * @throws FitsException if the operation failed
103      * 
104      * @return               the number of rows in the adapted table
105      * 
106      * @see                  #setRow(int, Object[])
107      * @see                  #addRowEntries(Object...)
108      * @see                  #deleteRows(int, int)
109      */
110     default int addRowEntries(Object... entries) throws FitsException {
111         return addRow(entries);
112     }
113 
114     /**
115      * Removes a set of consecutive columns from this table, without updating assocu=iated the header information for
116      * the columns that were removed. You should not use this method on tables already in an HDU, since it will not
117      * update the HDUs headers. Instead you should always create a new HDU for the table after editing, adding or
118      * migrating any custom header entries as necessary after.
119      * 
120      * @param  col           the 0-based index of the first column to remove
121      * @param  len           the number of subsequent columns to remove
122      * 
123      * @throws FitsException if the table could not be modified
124      * 
125      * @see                  #addColumn(Object)
126      * @see                  #deleteRows(int, int)
127      * @see                  #updateAfterDelete(int, Header)
128      */
129     void deleteColumns(int col, int len) throws FitsException;
130 
131     /**
132      * Removes a set of consecutive rows from this table without updating any associated header information for an
133      * encompassing HDU. You should not use this method on tables already in an HDU, since it will not update the HDUs
134      * headers. Instead you should always create a new HDU for the table after editing, adding or migrating any custom
135      * header entries as necessary after.
136      * 
137      * @param  row           the 0-based index of the first row to remove
138      * @param  len           the number of subsequent rows to remove
139      * 
140      * @throws FitsException if the table could not be modified
141      * 
142      * @see                  #addRow(Object[])
143      * @see                  #deleteColumns(int, int)
144      */
145     void deleteRows(int row, int len) throws FitsException;
146 
147     /**
148      * <p>
149      * Returns the data for a particular column in as an array of elements. See {@link #addColumn(Object)} for more
150      * information about the format of data elements in general.
151      * </p>
152      * 
153      * @param  col           The 0-based column index.
154      * 
155      * @return               an array of primitives (for scalar columns), or else an <code>Object[]</code> array, or
156      *                           possibly <code>null</code>
157      * 
158      * @throws FitsException if the table could not be accessed
159      * 
160      * @see                  #setColumn(int, Object)
161      * @see                  #getElement(int, int)
162      * @see                  #getNCols()
163      */
164     Object getColumn(int col) throws FitsException;
165 
166     /**
167      * <p>
168      * Returns the data element in this table. Elements are always stored as arrays even when scalar types. Thus a
169      * single <code>double</code> value will be returned as a <code>double[1]</code>. For most column types the storage
170      * type of the array matches that of their native Java type, but there are exceptions:
171      * </p>
172      * <ul>
173      * <li>Character arrays in FITS are stored as <code>byte[]</code> or <code>short[]</code>, depending on the
174      * {@link nom.tam.fits.FitsFactory#setUseUnicodeChars(boolean)} setting, not unicode Java <code>char[]</code>.
175      * Therefore, this call will return <code>byte[]</code> or <code>short[]</code>, the same as for a byte or 16-bit
176      * integer array. As a result if a new table is created with the returned data, the new table column will change its
177      * FITS column type from <code>A</code> to <code>B</code> or <code>I</code>.</li>
178      * <li>Complex values in FITS are stored as <code>float[2]</code> or <code>double[2]</code>, not as a
179      * {@link ComplexValue} type. Therefore, this call will return <code>float[]</code> or <code>double[]</code>, the
180      * same as for a float array. As a result if a new table is created with the returned data, the new table column
181      * will change it's FITS column type from <code>C</code> to <code>F</code>, or from <code>M</code> to
182      * <code>D</code>,.</li>
183      * </ul>
184      * 
185      * @param  row           the 0-based row index of the element
186      * @param  col           the 0-based column index of the element
187      * 
188      * @return               A primitive array containing the data for the the specified (row, col) entry in the table.
189      * 
190      * @throws FitsException if the table could not be accessed
191      * 
192      * @see                  #setElement(int, int, Object)
193      * @see                  #getNRows()
194      * @see                  #getNCols()
195      */
196     Object getElement(int row, int col) throws FitsException;
197 
198     /**
199      * Returns the number of columns contained in this table.
200      * 
201      * @return the current number of columns in the table.
202      * 
203      * @see    #getNRows()
204      * @see    #getColumn(int)
205      * @see    #setColumn(int, Object)
206      */
207     int getNCols();
208 
209     /**
210      * Returns the number of columns contained in this table.
211      * 
212      * @return the current number of columns in the table.
213      * 
214      * @see    #getNRows()
215      * @see    #getColumn(int)
216      * @see    #setColumn(int, Object)
217      */
218     int getNRows();
219 
220     /**
221      * Returns an array of elements in a particualr table row. See {@link #getElement(int, int)} for more information
222      * about the format of each element in the row.
223      * 
224      * @param  row           the 0-based row index
225      * 
226      * @return               an object containing the row data (for all column) of the specified row, or possubly
227      *                           <code>null</code>. See {@link #getElement(int, int)} for more information about the
228      *                           format of each element in the row.
229      * 
230      * @throws FitsException if the table could not be accessed
231      * 
232      * @see                  #getNRows()
233      * @see                  #setRow(int, Object[])
234      * @see                  #getColumn(int)
235      * @see                  #getElement(int, int)
236      */
237     Object[] getRow(int row) throws FitsException;
238 
239     /**
240      * Sets new data for a table column. See {@link #addColumn(Object)} for more information on the column data format.
241      * 
242      * @param  col           the 0-based column index
243      * @param  newCol        an object containing the new column data (for all rows) of the specified column. See
244      *                           {@link #getColumn(int)} for more information on the column data format.
245      * 
246      * @throws FitsException if the table could not be modified
247      * 
248      * @see                  #getNCols()
249      * @see                  #getColumn(int)
250      * @see                  #setRow(int, Object[])
251      * @see                  #setElement(int, int, Object)
252      */
253     void setColumn(int col, Object newCol) throws FitsException;
254 
255     /**
256      * Sets new data element in this table. See {@link #getElement(int, int)} for more information about the format of
257      * elements.
258      * 
259      * @param  row           the 0-based row index of the element
260      * @param  col           the 0-based column index of the element
261      * @param  element       the new element at the specified table location as a primitive array.
262      * 
263      * @throws FitsException if the table could not be modified
264      * 
265      * @see                  #getElement(int, int)
266      * @see                  #getNRows()
267      * @see                  #getNCols()
268      */
269     void setElement(int row, int col, Object element) throws FitsException;
270 
271     /**
272      * Sets new data for a table row. See {@link #getElement(int, int)} for more information about the format of
273      * elements.
274      * 
275      * @param  row           the 0-based row index
276      * @param  newRow        an object containing the row data (for all column) of the specified row. See
277      *                           {@link #getElement(int, int)} for more information about the format of each element in
278      *                           the row.
279      * 
280      * @throws FitsException if the table could not be modified
281      * 
282      * @see                  #setRowEntries(int, Object...)
283      * @see                  #getNRows()
284      * @see                  #getRow(int)
285      * @see                  #setColumn(int, Object)
286      * @see                  #setElement(int, int, Object)
287      */
288     void setRow(int row, Object[] newRow) throws FitsException;
289 
290     /**
291      * Like {@link #setRow(int, Object[])} but with vararg list of entries.
292      * 
293      * @param  row           the 0-based row index
294      * @param  entries       an object containing the row data (for all column) of the specified row. See
295      *                           {@link #getElement(int, int)} for more information about the format of each element in
296      *                           the row.
297      * 
298      * @throws FitsException if the table could not be modified
299      * 
300      * @see                  #setRow(int, Object[])
301      * @see                  #addRowEntries(Object...)
302      * @see                  #setElement(int, int, Object)
303      */
304     default void setRowEntries(int row, Object... entries) throws FitsException {
305         setRow(row, entries);
306     }
307 
308     /**
309      * Updates the table dimensions in the header following deletion. Whoever calls {@link #deleteColumns(int, int)} on
310      * this table should call this method after the deletion(s), at least once after all desired column deletions have
311      * been processed).
312      * 
313      * @param      oldNcol       The number of columns in the table before the first call to
314      *                               {@link #deleteColumns(int, int)}.
315      * @param      hdr           The table header
316      * 
317      * @throws     FitsException if the header could not be updated
318      * 
319      * @deprecated               It is not entirely foolproof for keeping the header in sync -- it is better to (re)wrap
320      *                               tables in a new HDU after column deletions, and then edit the new header as
321      *                               necessary to incorporate custom entries. May be removed from the API in the future.
322      */
323     void updateAfterDelete(int oldNcol, Header hdr) throws FitsException;
324 
325 }