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 }