1 package nom.tam.fits; 2 3 import nom.tam.fits.header.GenericKey; 4 import nom.tam.fits.header.IFitsHeader; 5 6 import static nom.tam.fits.header.Standard.NAXISn; 7 import static nom.tam.fits.header.Standard.TFIELDS; 8 import static nom.tam.fits.header.Standard.TFORMn; 9 import static nom.tam.fits.header.Standard.TTYPEn; 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 /** 43 * Base class for binary and ASCII table implementations. 44 * 45 * @param <T> the generic type of table data contained in this HDU instance. 46 */ 47 @SuppressWarnings("deprecation") 48 public abstract class TableHDU<T extends AbstractTableData> extends BasicHDU<T> { 49 50 /** 51 * Returns the default name for a columns with the specified index, to use if no column name was explicitly defined 52 * 53 * @param col The zero-based Java index of the column 54 * 55 * @return The default column name to use if no other name was defined. 56 * 57 * @since 1.20 58 * 59 * @see #setColumnName(int, String, String) 60 */ 61 public static String getDefaultColumnName(int col) { 62 return "Column " + (col + 1); 63 } 64 65 /** 66 * Create the TableHDU. Note that this will normally only be invoked by subclasses in the FITS package. 67 * 68 * @deprecated intended for internal use. Its visibility should be reduced to package level in the future. 69 * 70 * @param hdr the header 71 * @param td The data for the table. 72 */ 73 @Deprecated 74 protected TableHDU(Header hdr, T td) { 75 super(hdr, td); 76 } 77 78 /** 79 * Add a column to the table without any associated header information. 80 * 81 * @param newCol the new column information. the newCol should be an Object[] where type of all of the 82 * constituents is identical. The length of data should match the other columns. <b> 83 * Note:</b> It is valid for data to be a 2 or higher dimensionality primitive array. In 84 * this case the column index is the first (in Java speak) index of the array. E.g., if 85 * called with int[30][20][10], the number of rows in the table should be 30 and this 86 * column will have elements which are 2-d integer arrays with TDIM = (10,20). 87 * 88 * @return the number of columns in the adapted table 89 * 90 * @throws FitsException if the operation failed 91 */ 92 public int addColumn(Object newCol) throws FitsException { 93 int nCols = getNCols(); 94 myHeader.findCard(TFIELDS).setValue(nCols); 95 return nCols; 96 } 97 98 /** 99 * Add a row to the end of the table. If this is the first row, then this will add appropriate columns for each of 100 * the entries. The rows to add must be supplied as column based array of arrays. 101 * 102 * @return the number of rows in the adapted table 103 * 104 * @param newRows rows to add to the table 105 * 106 * @throws FitsException if the operation failed 107 */ 108 public int addRow(Object[] newRows) throws FitsException { 109 int row = myData.addRow(newRows); 110 myHeader.findCard(NAXISn.n(2)).setValue(getNRows()); 111 return row; 112 } 113 114 /** 115 * Returns the list of column description keyword stems that descrive this column in the FITS header. 116 * 117 * @return the stems of the keywords that are associated with table columns. Users can supplement this with their 118 * own and call the appropriate deleteColumns fields. 119 */ 120 protected abstract IFitsHeader[] columnKeyStems(); 121 122 /** 123 * Delete a set of columns from a table. 124 * 125 * @param column The one-indexed start column. 126 * @param len The number of columns to delete. 127 * 128 * @throws FitsException if the operation failed 129 * 130 * @deprecated It is not entirely foolproof for keeping the header in sync -- it is better to use 131 * {@link TableData#deleteColumns(int, int)} to edit tables before wrapping them in an 132 * HDU and editing the header as necessary to incorporate custom entries. May be 133 * removed from the API in the future. 134 */ 135 @Deprecated 136 public void deleteColumnsIndexOne(int column, int len) throws FitsException { 137 deleteColumnsIndexZero(column - 1, len); 138 } 139 140 /** 141 * Delete a set of columns from a table. 142 * 143 * @param column The one-indexed start column. 144 * @param len The number of columns to delete. 145 * @param fields Stems for the header fields to be removed for the table. 146 * 147 * @throws FitsException if the operation failed 148 * 149 * @deprecated It is not entirely foolproof for keeping the header in sync -- it is better to use 150 * {@link TableData#deleteColumns(int, int)} to edit tables before wrapping them in an 151 * HDU and editing the header as necessary to incorporate custom entries. May be 152 * removed from the API in the future. 153 */ 154 @Deprecated 155 public void deleteColumnsIndexOne(int column, int len, String[] fields) throws FitsException { 156 deleteColumnsIndexZero(column - 1, len, GenericKey.create(fields)); 157 } 158 159 /** 160 * Delete a set of columns from a table. 161 * 162 * @param column The one-indexed start column. 163 * @param len The number of columns to delete. 164 * 165 * @throws FitsException if the operation failed 166 * 167 * @deprecated It is not entirely foolproof for keeping the header in sync -- it is better to use 168 * {@link TableData#deleteColumns(int, int)} to edit tables before wrapping them in an 169 * HDU and editing the header as necessary to incorporate custom entries. May be 170 * removed from the API in the future. 171 */ 172 @Deprecated 173 public void deleteColumnsIndexZero(int column, int len) throws FitsException { 174 deleteColumnsIndexZero(column, len, columnKeyStems()); 175 } 176 177 /** 178 * Delete a set of columns from a table. 179 * 180 * @param column The zero-indexed start column. 181 * @param len The number of columns to delete. 182 * @param fields Stems for the header fields to be removed for the table. 183 * 184 * @throws FitsException if the operation failed 185 * 186 * @deprecated It is not entirely foolproof for keeping the header in sync -- it is better to use 187 * {@link TableData#deleteColumns(int, int)} to edit tables before wrapping them in an 188 * HDU and editing the header as necessary to incorporate custom entries. May be 189 * removed from the API in the future. 190 */ 191 @Deprecated 192 public void deleteColumnsIndexZero(int column, int len, IFitsHeader[] fields) throws FitsException { 193 194 if (column < 0 || len < 0 || column + len > getNCols()) { 195 throw new FitsException("Illegal columns deletion request- Start:" + column + " Len:" + len 196 + " from table with " + getNCols() + " columns"); 197 } 198 199 if (len == 0) { 200 return; 201 } 202 203 int ncol = getNCols(); 204 myData.deleteColumns(column, len); 205 206 // Get rid of the keywords for the deleted columns 207 for (int col = column; col < column + len; col++) { 208 for (IFitsHeader field : fields) { 209 myHeader.deleteKey(field.n(col + 1)); 210 } 211 } 212 213 // Shift the keywords for the columns after the deleted columns 214 for (int col = column + len; col < ncol; col++) { 215 for (IFitsHeader field : fields) { 216 IFitsHeader oldKey = field.n(col + 1); 217 IFitsHeader newKey = field.n(col + 1 - len); 218 if (myHeader.containsKey(oldKey)) { 219 myHeader.replaceKey(oldKey, newKey); 220 } 221 } 222 } 223 // Update the number of fields. 224 myHeader.getCard(TFIELDS).setValue(getNCols()); 225 226 // Give the data sections a chance to update the header too. 227 myData.updateAfterDelete(ncol, myHeader); 228 } 229 230 /** 231 * Remove all rows from the table starting at some specific index from the table. Inspired by a routine by R. Mathar 232 * but re-implemented using the DataTable and changes to AsciiTable so that it can be done easily for both Binary 233 * and ASCII tables. 234 * 235 * @param row the (0-based) index of the first row to be deleted. 236 * 237 * @throws FitsException if an error occurs. 238 * 239 * @deprecated It is not entirely foolproof for keeping the header in sync -- it is better to use 240 * {@link TableData#deleteRows(int, int)} to edit tables before wrapping them in an 241 * HDU and editing the header as necessary to incorporate custom entries. May be 242 * removed from the API in the future. 243 */ 244 @Deprecated 245 public void deleteRows(final int row) throws FitsException { 246 deleteRows(row, getNRows() - row); 247 } 248 249 /** 250 * Remove a number of adjacent rows from the table. This routine was inspired by code by R.Mathar but re-implemented 251 * using changes in the ColumnTable class abd AsciiTable so that we can do it for all FITS tables. 252 * 253 * @param firstRow the (0-based) index of the first row to be deleted. This is zero-based indexing: 254 * 0<=firstrow< number of rows. 255 * @param nRow the total number of rows to be deleted. 256 * 257 * @throws FitsException If an error occurs in the deletion. 258 * 259 * @deprecated It is not entirely foolproof for keeping the header in sync -- it is better to use 260 * {@link TableData#deleteRows(int, int)} to edit tables before wrapping them in an 261 * HDU and editing the header as necessary to incorporate custom entries. May be 262 * removed from the API in the future. 263 */ 264 @Deprecated 265 public void deleteRows(final int firstRow, int nRow) throws FitsException { 266 267 // Just ignore invalid requests. 268 if (nRow <= 0 || firstRow >= getNRows() || firstRow <= 0) { 269 return; 270 } 271 272 /* correct if more rows are requested than available */ 273 if (nRow > getNRows() - firstRow) { 274 nRow = getNRows() - firstRow; 275 } 276 277 myData.deleteRows(firstRow, nRow); 278 myHeader.setNaxis(2, getNRows()); 279 } 280 281 /** 282 * Find the 0-based column index corresponding to a particular column name. 283 * 284 * @return index of the column 285 * 286 * @param colName the name of the column 287 */ 288 public int findColumn(String colName) { 289 for (int i = 0; i < getNCols(); i++) { 290 String val = myHeader.getStringValue(TTYPEn.n(i + 1)); 291 if (val != null && val.trim().equals(colName)) { 292 return i; 293 } 294 } 295 return -1; 296 } 297 298 /** 299 * <p> 300 * Returns the data for a particular column in as an array of elements. See {@link TableData#addColumn(Object)} for 301 * more information about the format of data elements in general. 302 * </p> 303 * 304 * @param col The 0-based column index. 305 * 306 * @return an array of primitives (for scalar columns), or else an <code>Object[]</code> array, or 307 * possibly <code>null</code> 308 * 309 * @throws FitsException if the table could not be accessed 310 * 311 * @see TableData#getColumn(int) 312 * @see #setColumn(int, Object) 313 * @see #getElement(int, int) 314 * @see #getNCols() 315 */ 316 public Object getColumn(int col) throws FitsException { 317 return myData.getColumn(col); 318 } 319 320 /** 321 * <p> 322 * Returns the data for a particular column in as an array of elements. See {@link TableData#addColumn(Object)} for 323 * more information about the format of data elements in general. 324 * </p> 325 * 326 * @param colName The name or ID of the column as stored by the <code>TTYPE</code><i>n</i> FITS header 327 * keyword. 328 * 329 * @return an array of primitives (for scalar columns), or else an <code>Object[]</code> array, or 330 * possibly <code>null</code> 331 * 332 * @throws FitsException if the table could not be accessed 333 * 334 * @see TableData#getColumn(int) 335 * @see #setColumn(int, Object) 336 * @see #getElement(int, int) 337 * @see #getNCols() 338 */ 339 public Object getColumn(String colName) throws FitsException { 340 return getColumn(findColumn(colName)); 341 } 342 343 /** 344 * Get the FITS type of a column in the table. 345 * 346 * @param index The 0-based index of the column. 347 * 348 * @return The FITS type. 349 * 350 * @throws FitsException if an invalid index was requested. 351 */ 352 public String getColumnFormat(int index) throws FitsException { 353 int flds = myHeader.getIntValue(TFIELDS, 0); 354 if (index < 0 || index >= flds) { 355 throw new FitsException("Bad column index " + index + " (only " + flds + " columns)"); 356 } 357 358 return myHeader.getStringValue(TFORMn.n(index + 1)).trim(); 359 } 360 361 /** 362 * Convenience method for getting column data. Note that this works only for metadata that returns a string value. 363 * This is equivalent to getStringValue(type+index); 364 * 365 * @return meta data string value 366 * 367 * @param index index of the colum 368 * @param type the key type to get 369 */ 370 public String getColumnMeta(int index, String type) { 371 return myHeader.getStringValue(type + (index + 1)); 372 } 373 374 /** 375 * Gets the name of a column in the table, as it appears in this HDU's header. It may differ from a more currently 376 * assigned name of the binary table data column after the HDU creation or reading. 377 * 378 * @param index The 0-based column index. 379 * 380 * @return The column name. 381 * 382 * @see BinaryTable.ColumnDesc#name() 383 */ 384 public String getColumnName(int index) { 385 386 String ttype = myHeader.getStringValue(TTYPEn.n(index + 1)); 387 if (ttype != null) { 388 ttype = ttype.trim(); 389 } 390 return ttype; 391 } 392 393 /** 394 * <p> 395 * Returns the data for all columns in as an array. See {@link TableData#addColumn(Object)} for more information 396 * about the column format of each element in the returned array. 397 * </p> 398 * 399 * @return An array containing the column data for all columns. Each entry in the returned array is 400 * itself an array of primitives (for scalar columns), or else an <code>Object[]</code> 401 * array, or possibly <code>null</code>. 402 * 403 * @throws FitsException if the table could not be accessed 404 * 405 * @see TableData#getColumn(int) 406 * @see #setColumn(int, Object) 407 * @see #getElement(int, int) 408 * @see #getNCols() 409 */ 410 public Object[] getColumns() throws FitsException { 411 Object[] result = new Object[getNCols()]; 412 for (int i = 0; i < result.length; i++) { 413 result[i] = getColumn(i); 414 } 415 return result; 416 } 417 418 /** 419 * Returns a specific element from this table 420 * 421 * @return a specific element of the table using 0-based indices. 422 * 423 * @param row the row index of the element 424 * @param col the column index of the element 425 * 426 * @throws FitsException if the operation failed 427 * 428 * @see #getElement(int, int) 429 */ 430 public Object getElement(int row, int col) throws FitsException { 431 return myData.getElement(row, col); 432 } 433 434 /** 435 * Get the number of columns for this table 436 * 437 * @return The number of columns in the table. 438 */ 439 public int getNCols() { 440 return myData.getNCols(); 441 } 442 443 /** 444 * Get the number of rows for this table 445 * 446 * @return The number of rows in the table. 447 */ 448 public int getNRows() { 449 return myData.getNRows(); 450 } 451 452 /** 453 * Returns a specific row from this table 454 * 455 * @return a specific row of the table. 456 * 457 * @param row the index of the row to retreive 458 * 459 * @throws FitsException if the operation failed 460 * 461 * @see #setRow(int, Object[]) 462 */ 463 public Object[] getRow(int row) throws FitsException { 464 return myData.getRow(row); 465 } 466 467 /** 468 * Update a column within a table. The new column should have the same format ast the column being replaced. See 469 * {@link TableData#addColumn(Object)} for more information about the column data format. 470 * 471 * @param col index of the column to replace 472 * @param newCol the replacement column 473 * 474 * @throws FitsException if the operation failed 475 * 476 * @see #getColumn(int) 477 * @see #setColumn(String, Object) 478 * @see TableData#addColumn(Object) 479 */ 480 public void setColumn(int col, Object newCol) throws FitsException { 481 myData.setColumn(col, newCol); 482 } 483 484 /** 485 * Update a column within a table. The new column should have the same format as the column being replaced. See 486 * {@link TableData#addColumn(Object)} for more information about the column data format. 487 * 488 * @param colName name of the column to replace 489 * @param newCol the replacement column 490 * 491 * @throws FitsException if the operation failed 492 * 493 * @see #getColumn(String) 494 * @see #setColumn(int, Object) 495 * @see TableData#addColumn(Object) 496 */ 497 public void setColumn(String colName, Object newCol) throws FitsException { 498 setColumn(findColumn(colName), newCol); 499 } 500 501 /** 502 * Specify column metadata for a given column in a way that allows all of the column metadata for a given column to 503 * be organized together. 504 * 505 * @param index The 0-based index of the column 506 * @param key The column key. I.e., the keyword will be key+(index+1) 507 * @param value The value to be placed in the header. 508 * @param comment The comment for the header 509 * @param after Should the header card be after the current column metadata block 510 * (<code>true</code>), or immediately before the TFORM card (<code>false</code>). 511 * 512 * @throws HeaderCardException if the header could not be updated 513 */ 514 public void setColumnMeta(int index, IFitsHeader key, String value, String comment, boolean after) 515 throws HeaderCardException { 516 setCurrentColumn(index, after); 517 myHeader.addLine(new HeaderCard(key.n(index + 1).key(), value, comment)); 518 } 519 520 /** 521 * Specify column metadata for a given column in a way that allows all of the column metadata for a given column to 522 * be organized together. 523 * 524 * @param index The 0-based index of the column 525 * @param key The column key. I.e., the keyword will be key+(index+1) 526 * @param value The value to be placed in the header. 527 * @param comment The comment for the header 528 * @param after Should the header card be after the current column metadata block 529 * (<code>true</code>), or immediately before the TFORM card (<code>false</code>). 530 * 531 * @throws HeaderCardException if the header could not be updated 532 * 533 * @since 1.16 534 */ 535 public void setColumnMeta(int index, IFitsHeader key, Number value, String comment, boolean after) 536 throws HeaderCardException { 537 setCurrentColumn(index, after); 538 myHeader.addLine(new HeaderCard(key.n(index + 1).key(), value, comment)); 539 } 540 541 /** 542 * Specify column metadata for a given column in a way that allows all of the column metadata for a given column to 543 * be organized together. 544 * 545 * @param index The 0-based index of the column 546 * @param key The column key. I.e., the keyword will be key+(index+1) 547 * @param value The value to be placed in the header. 548 * @param comment The comment for the header 549 * @param after Should the header card be after the current column metadata block 550 * (<code>true</code>), or immediately before the TFORM card (<code>false</code>). 551 * 552 * @throws HeaderCardException if the header could not be updated 553 */ 554 public void setColumnMeta(int index, String key, Boolean value, String comment, boolean after) 555 throws HeaderCardException { 556 setCurrentColumn(index, after); 557 myHeader.addLine(new HeaderCard(key + (index + 1), value, comment)); 558 } 559 560 /** 561 * Specify column metadata for a given column in a way that allows all of the column metadata for a given column to 562 * be organized together. 563 * 564 * @param index The 0-based index of the column 565 * @param key The column key. I.e., the keyword will be key+(index+1) 566 * @param value The value to be placed in the header. 567 * @param comment The comment for the header 568 * @param after Should the header card be after the current column metadata block 569 * (<code>true</code>), or immediately before the TFORM card (<code>false</code>). 570 * 571 * @throws HeaderCardException if the header could not be updated 572 */ 573 public void setColumnMeta(int index, String key, Number value, String comment, boolean after) 574 throws HeaderCardException { 575 setCurrentColumn(index, after); 576 myHeader.addLine(new HeaderCard(key + (index + 1), value, comment)); 577 } 578 579 /** 580 * Specify column metadata for a given column in a way that allows all of the column metadata for a given column to 581 * be organized together. 582 * 583 * @param index The 0-based index of the column 584 * @param key The column key. I.e., the keyword will be key+(index+1) 585 * @param value The value to be placed in the header. 586 * @param precision The maximum number of decimal places to show after the leading figure. (Trailing 587 * zeroes will be ommitted.) 588 * @param comment The comment for the header 589 * @param after Should the header card be after the current column metadata block 590 * (<code>true</code>), or immediately before the TFORM card (<code>false</code>). 591 * 592 * @throws HeaderCardException if the header could not be updated 593 */ 594 public void setColumnMeta(int index, String key, Number value, int precision, String comment, boolean after) 595 throws HeaderCardException { 596 setCurrentColumn(index, after); 597 myHeader.addLine(new HeaderCard(key + (index + 1), value, precision, comment)); 598 } 599 600 /** 601 * Specify column metadata for a given column in a way that allows all of the column metadata for a given column to 602 * be organized together. 603 * 604 * @param index The 0-based index of the column 605 * @param key The column key. I.e., the keyword will be key+(index+1) 606 * @param value The value to be placed in the header. 607 * @param comment The comment for the header 608 * 609 * @throws HeaderCardException if the header could not be updated 610 */ 611 public void setColumnMeta(int index, String key, String value, String comment) throws HeaderCardException { 612 setColumnMeta(index, key, value, comment, true); 613 } 614 615 /** 616 * Specify column metadata for a given column in a way that allows all of the column metadata for a given column to 617 * be organized together. 618 * 619 * @param index The 0-based index of the column 620 * @param key The column key. I.e., the keyword will be key+(index+1) 621 * @param value The value to be placed in the header. 622 * @param comment The comment for the header 623 * @param after Should the header card be after the current column metadata block (true), or 624 * immediately before the TFORM card (false). @throws FitsException if the 625 * operation failed 626 * 627 * @throws HeaderCardException if the header could not be updated 628 * 629 * @deprecated use {@link #setColumnMeta(int, IFitsHeader, String, String, boolean)} 630 */ 631 @Deprecated 632 public void setColumnMeta(int index, String key, String value, String comment, boolean after) 633 throws HeaderCardException { 634 setCurrentColumn(index, after); 635 myHeader.addLine(new HeaderCard(key + (index + 1), value, comment)); 636 } 637 638 /** 639 * Sets the name / ID of a specific column in this table. Naming columns is generally a good idea so that people can 640 * figure out what sort of data actually appears in specific table columns. 641 * 642 * @param index the column index 643 * @param name the name or ID we want to assing to the column 644 * @param comment Any additional comment we would like to store alongside in the FITS header. 645 * (The comment may be truncated or even ommitted, depending on space 646 * constraints in the FITS header. 647 * 648 * @throws IndexOutOfBoundsException if the table has no column matching the index 649 * @throws HeaderCardException if there was a problem wil adding the associated descriptive FITS header 650 * keywords to this table's header. 651 * 652 * @see #getColumnName(int) 653 * @see #getDefaultColumnName(int) 654 */ 655 public void setColumnName(int index, String name, String comment) 656 throws IndexOutOfBoundsException, HeaderCardException { 657 if (index < 0 || index >= getNCols()) { 658 throw new IndexOutOfBoundsException( 659 "column index " + index + " is out of bounds for table with " + getNCols() + " columns"); 660 } 661 setColumnMeta(index, TTYPEn, name, comment, true); 662 } 663 664 /** 665 * Set the cursor in the header to point after the metadata for the specified column 666 * 667 * @param col The 0-based index of the column 668 * 669 * @deprecated (<i>for internal use</i>) Will be removed int the future (no longer used). 670 */ 671 @Deprecated 672 public void setCurrentColumn(int col) { 673 setCurrentColumn(col, true); 674 } 675 676 /** 677 * Set the cursor in the header to point either before the TFORMn value or after the column metadata 678 * 679 * @param col The 0-based index of the column 680 * @param after True if the cursor should be placed after the existing column metadata or false if the cursor 681 * is to be placed before the TFORM value. If no corresponding TFORM is found, the cursor will 682 * be placed at the end of current header. 683 * 684 * @deprecated (<i>for internal use</i>) Will have private access in the future. 685 */ 686 @Deprecated 687 public void setCurrentColumn(int col, boolean after) { 688 if (after) { 689 myHeader.positionAfterIndex(TFORMn, col + 1); 690 } else { 691 myHeader.findCard(TFORMn.n(col + 1)); 692 } 693 } 694 695 /** 696 * Update a single element within the table. 697 * 698 * @param row the row index 699 * @param col the column index 700 * @param element the replacement element 701 * 702 * @throws FitsException if the operation failed 703 * 704 * @see #getElement(int, int) 705 */ 706 public void setElement(int row, int col, Object element) throws FitsException { 707 myData.setElement(row, col, element); 708 } 709 710 /** 711 * Update a row within a table. 712 * 713 * @param row row index 714 * @param newRow the replacement row 715 * 716 * @throws FitsException if the operation failed 717 * 718 * @see #getRow(int) 719 */ 720 public void setRow(int row, Object[] newRow) throws FitsException { 721 myData.setRow(row, newRow); 722 } 723 }