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 }