📄 fxbgrow.pro
字号:
PRO FXBGROW, UNIT, HEADER, NROWS, ERRMSG=ERRMSG, NOZERO=NOZERO, $ BUFFERSIZE=BUFFERSIZE0;+; NAME: ; FXBGROW; PURPOSE : ; Increase the number of rows in a binary table.; EXPLANATION : ; Call FXBGROW to increase the size of an already-existing FITS; binary table. The number of rows increases to NROWS; however; the table cannot shrink by this operation. This procedure is; useful when a table with an unknown number of rows must be; created. The caller would then call FXBCREATE to construct a; table of some base size, and follow with calls to FXBGROW to; lengthen the table as needed. The extension being enlarged; need not be the last extension in the file. If subsequent; extensions exist in the file, they will be shifted properly.;; CALLING SEQUENCE :; FXBGROW, UNIT, HEADER, NROWS[, ERRMSG= , NOZERO= , BUFFERSIZE= ];; INPUT PARAMETERS :; UNIT = Logical unit number of an already-opened file.; HEADER = String array containing the FITS binary table extension; header. The header is modified in place.; NROWS = New number of rows, always more than the previous; number.;; OPTIONAL INPUT KEYWORDS:; NOZERO = when set, FXBGROW will not zero-pad the new data if; it doesn't have to.; ERRMSG = If defined and passed, then any error messages will be; returned to the user in this parameter rather than; depending on the MESSAGE routine in IDL. If no errors are; encountered, then a null string is returned. In order to; use this feature, ERRMSG must be defined first, e.g.;; ERRMSG = ''; FXBGROW, ERRMSG=ERRMSG, ...; IF ERRMSG NE '' THEN ...; BUFFERSIZE = Size in bytes for intermediate data transfers; (default 32768);; Calls : ; FXADDPAR, FXHREAD, BLKSHIFT; Common : ; Uses common block FXBINTABLE--see "fxbintable.pro" for more; information.; Restrictions: ; The file must be open with write permission.;; The binary table extension in question must already by written; to the file (using FXBCREATE).;; A table can never shrink via this operation.;; SIDE EFFECTS: ; The FITS file will grow in size, and heap areas are; preserved by moving them to the end of the file.;; The header is modified to reflect the new number of rows.; CATEGORY : ; Data Handling, I/O, FITS, Generic.; Initially written, C. Markwardt, GSFC, Nov 1998; Added ability to enlarge arbitrary extensions and tables with; variable sized rows, not just the last extension in a file,; CM, April 2000; Fix bug in the zeroing of the output file, C. Markwardt, April 2005;;-;@fxbintable ON_ERROR, 0;; Check the number of parameters.; IF N_PARAMS() NE 3 THEN BEGIN MESSAGE = 'Syntax: FXBGROW, UNIT, HEADER, NROWS' IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF;; Find the index of the file.; ILUN = WHERE(LUN EQ UNIT,NLUN) ILUN = ILUN[0] IF NLUN EQ 0 THEN BEGIN MESSAGE = 'Unit ' + STRTRIM(UNIT,2) + $ ' not opened properly' IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF;; Don't shrink the file.; IF NAXIS2[ILUN] GE NROWS THEN GOTO, FINISH;; Make sure the file was opened for write access.; IF STATE[ILUN] NE 2 THEN BEGIN MESSAGE = 'Unit ' + STRTRIM(UNIT,2) + $ ' not opened for write access' IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF;; Compute number of bytes and buffer size; NBYTES = (NROWS-NAXIS2[ILUN])*NAXIS1[ILUN] IF N_ELEMENTS(BUFFERSIZE0) EQ 0 THEN BUFFERSIZE0 = 32768L BUFFERSIZE = LONG(BUFFERSIZE0[0]) BUFFERSIZE = FLOOR(BUFFERSIZE/NAXIS1[ILUN])*NAXIS1[ILUN] IF BUFFERSIZE LE 0 THEN BUFFERSIZE = NAXIS1[ILUN];; First, shift the following extensions by block multiples; ;; Current beginning of next extension N_EXT = NHEADER[ILUN] + HEAP[ILUN] + DHEAP[ILUN] ;; New beginning of next extension, after shifting N_EXT1 = N_EXT + NBYTES ;; Round to nearest block size IF N_EXT MOD 2880 NE 0 THEN N_EXT = N_EXT + 2880 - (N_EXT MOD 2880) IF N_EXT1 MOD 2880 NE 0 THEN N_EXT1 = N_EXT1 + 2880 - (N_EXT1 MOD 2880) NBYTES1 = N_EXT1 - N_EXT ERRMSG1 = '' IF NBYTES1 GT 0 THEN BEGIN BLKSHIFT, UNIT, N_EXT, NBYTES1, ERRMSG=ERRMSG1, $ NOZERO=KEYWORD_SET(NOZERO), BUFFERSIZE=BUFFERSIZE IF ERRMSG1 NE '' THEN GOTO, RETMESSAGE ENDIF;; Next, shift the data between the end of the table and the next; extension, if any.; ;; End of table data (but before variable-sized heap data) ETAB = NHEADER[ILUN] + NAXIS1[ILUN]*NAXIS2[ILUN] IF N_EXT GT ETAB THEN BEGIN BLKSHIFT, UNIT, [ETAB, N_EXT1-NBYTES-1L], NBYTES, ERRMSG=ERRMSG1, $ NOZERO=KEYWORD_SET(NOZERO), BUFFERSIZE=BUFFERSIZE ENDIF RETMESSAGE: IF ERRMSG1 NE '' THEN BEGIN MESSAGE = ERRMSG1 IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF;; Zero-fill if necessary (if the original table had no trailing; extensions); FS = FSTAT(UNIT) IF FS.SIZE LT N_EXT1 AND NOT KEYWORD_SET(NOZERO) THEN BEGIN POINT_LUN, UNIT, ETAB NLEFT = N_EXT1 - ETAB NBUFF = BUFFERSIZE < NLEFT BB = BYTARR(NBUFF) WHILE NLEFT GT 0 DO BEGIN WRITEU, UNIT, BB NLEFT = NLEFT - N_ELEMENTS(BB) IF (NLEFT LT NBUFF) AND (NLEFT GT 0) THEN BB = BB[0:NLEFT-1] ENDWHILE ENDIF;; Update the internal state.; HEAP[ILUN] = HEAP[ILUN] + NBYTES NAXIS2[ILUN] = NROWS;; Modify passed copy of header; IF N_ELEMENTS(HEADER) GT 0 THEN BEGIN FXADDPAR, HEADER, 'NAXIS2', LONG(NROWS), 'Number of rows (grown)' THEAP = FXPAR(HEADER, 'THEAP', COUNT=COUNT) IF COUNT GT 0 THEN BEGIN THEAP = THEAP + NBYTES FXADDPAR, HEADER, 'THEAP', THEAP, 'Offset of heap' ENDIF ENDIF;; Modify internal copy of HEADER; XHEADER = HEAD[*,ILUN] FXADDPAR, XHEADER, 'NAXIS2', LONG(NROWS), 'Number of rows (grown)' THEAP = FXPAR(XHEADER, 'THEAP', COUNT=COUNT) IF COUNT GT 0 THEN BEGIN THEAP = THEAP + NBYTES FXADDPAR, XHEADER, 'THEAP', THEAP, 'Offset of heap' ENDIF HEAD[*,ILUN] = XHEADER;; Modify disk copy of HEADER; POINT_LUN, UNIT, MHEADER[ILUN] FXHREAD, UNIT, DHEADER, STATUS IF STATUS NE 0 THEN BEGIN MESSAGE = 'Could not load header from file' IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF FXADDPAR, DHEADER, 'NAXIS2', LONG(NROWS), 'Number of rows (grown)' THEAP = FXPAR(DHEADER, 'THEAP', COUNT=COUNT) IF COUNT GT 0 THEN BEGIN THEAP = THEAP + NBYTES FXADDPAR, DHEADER, 'THEAP', THEAP, 'Offset of heap' ENDIF ;; Don't worry about the header increasing in size, since ;; every binary table has to have NAXIS2 already. SLEN = STRLEN(DHEADER[0]) FULL = STRING(REPLICATE(32B, 80)) ;; Pad with spaces IF SLEN LT 80 THEN DHEADER[0] = DHEADER[0] + STRMID(FULL,0,80-SLEN) BHDR = BYTE(DHEADER) BHDR = BHDR[0:79,*] POINT_LUN, UNIT, MHEADER[ILUN] WRITEU, UNIT, BHDRFINISH: IF N_ELEMENTS(ERRMSG) NE 0 THEN ERRMSG = '' RETURN END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -