📄 fxbwritm.pro
字号:
PRO FXBWRITM, UNIT, COL, $ D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, $ D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, $ D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, $ D30, D31, D32, D33, D34, D35, D36, D37, D38, D39, $ D40, D41, D42, D43, D44, D45, D46, D47, D48, D49, $ NOIEEE=NOIEEE, NOSCALE=NOSCALE, $ POINTERS=POINTERS, PASS_METHOD=PASS_METHOD, $ ROW=ROW, NANVALUE=NANVALUE, BUFFERSIZE=BUFFERSIZE, $ ERRMSG=ERRMSG, WARNMSG=WARNMSG, STATUS=OUTSTATUS;+; NAME: ; FXBWRITM; PURPOSE: ; Write multiple columns/rows to a disk FITS binary table file.; EXPLANATION : ; A call to FXBWRITM will write multiple rows and multiple; columns to a binary table in a single procedure call. Up to; fifty columns may be read in a single pass. The file should; have already been opened with FXBOPEN (with write access) or; FXBCREATE. FXBWRITM optimizes writing multiple columns by; first writing a large chunk of data to the FITS file all at; once. FXBWRITM cannot write variable-length arrays; use; FXBWRITE instead.;; The number of columns is limited to 50 if data are passed by; positional argument. However, this limitation can be overcome; by passing pointers to FXBWRITM. The user should set the PASS_METHOD ; keyword to 'POINTER' as appropriate, and an array of pointers to ; the data in the POINTERS keyword. The user is responsible for freeing ; the pointers.;; CALLING SEQUENCE: ; FXBWRITM, UNIT, COL, D0, D1, D2, ..., [ ROW= , PASS_METHOD, NANVALUE=; POINTERS=, BUFFERSIZE= ]; ; INPUT PARAMETERS: ; UNIT = Logical unit number corresponding to the file containing the; binary table.; D0,..D49= An IDL data array to be written to the file, one for; each column. These parameters will be igonred if data; is passed through the POINTERS keyword.; COL = Column in the binary table to place data in. May be either; a list of column numbers where the first column is one, or ; a string list of column names. ; OPTIONAL INPUT KEYWORDS: ; ROW = Either row number in the binary table to write data to,; starting from row one, or a two element array containing a; range of row numbers to write. If not passed, then; the entire column is written.; NANVALUE= Value signalling data dropout. All points corresponding to; this value are set to be IEEE NaN (not-a-number). Ignored; unless DATA is of type float, double-precision or complex.; NOSCALE = If set, then TSCAL/TZERO values are ignored, and data is ; written exactly as supplied. ; PASS_METHOD = A scalar string indicating method of passing; data to FXBWRITM. One of 'ARGUMENT' (indicating; pass by positional argument), or'POINTER' (indicating; passing an array of pointers by the POINTERS; keyword). ; Default: 'ARGUMENT'; POINTERS = If PASS_METHOD is 'POINTER' then the user must pass; an array of IDL pointers to this keyword, one for; each column. Ultimately the user is responsible for ; deallocating pointers.; BUFFERSIZE = Data are transferred in chunks to conserve; memory. This is the size in bytes of each chunk.; If a value of zero is given, then all of the data; are transferred in one pass. Default is 32768 (32; kB).; OPTIONAL OUTPUT KEYWORDS:; 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 = ''; FXBWRITE, ERRMSG=ERRMSG, ...; IF ERRMSG NE '' THEN ...; WARNMSG = Messages which are considered to be non-fatal; "warnings" are returned in this output string.; STATUS = An output array containing the status for each; read, 1 meaning success and 0 meaning failure.;; PROCEDURE CALLS: ; None.; EXAMPLE:; Write a binary table 'sample.fits' giving 43 X,Y positions and a ; 21 x 21 PSF at each position:;; (1) First, create sample values; x = findgen(43) & y = findgen(43)+1 & psf = randomn(seed,21,21,43); ; (2) Create primary header, write it to disk, and make extension header; fxhmake,header,/initialize,/extend,/date; fxwrite,'sample.fits',header; fxbhmake,header,43,'TESTEXT','Test binary table extension';; (3) Fill extension header with desired column names; fxbaddcol,1,header,x[0],'X' ;Use first element in each array; fxbaddcol,2,header,y[0],'Y' ;to determine column properties; fxbaddcol,3,header,psf[*,*,0],'PSF';; (4) Write extension header to FITS file; fxbcreate,unit,'sample.fits',header;; (5) Use FXBWRITM to write all data to the extension in a single call; fxbwritm,unit,['X','Y','PSF'], x, y, psf; fxbfinish,unit ;Close the file;; COMMON BLOCKS: ; Uses common block FXBINTABLE--see "fxbintable.pro" for more; information.; RESTRICTIONS: ; The binary table file must have been opened with FXBCREATE or; FXBOPEN (with write access).;; The data must be consistent with the column definition in the binary; table header.;; The row number must be consistent with the number of rows stored in the; binary table header.;; A PASS_METHOD of POINTER does not use the EXECUTE() statement and can be; used with the IDL Virtual Machine. However, the EXECUTE() statement is; used when the PASS_METHOD is by arguments. ; CATEGORY: ; Data Handling, I/O, FITS, Generic.; PREVIOUS HISTORY: ; C. Markwardt, based on FXBWRITE and FXBREADM (ver 1), Jan 1999; WRITTEN: ; Craig Markwardt, GSFC, January 1999.; MODIFIED:; Version 1, Craig Markwardt, GSFC 18 January 1999.; Documented this routine, 18 January 1999. ; C. Markwardt, added ability to pass by handle or pointer.; Some bug fixes, 20 July 2001 ; W. Landsman/B.Schulz Allow more than 50 arguments when using pointers; W. Landsman Remove pre-V5.0 HANDLE options July 2004; W. Landsman Remove EXECUTE() call with POINTERS May 2005; C. Markwardt Allow the output table to have TSCAL/TZERO; keyword values; if that is the case, then the passed values; will be quantized to match those scale factors before being; written. Sep 2007; E. Hivon: write 64bit integer and double precison columns, Mar 2008; C. Markwardt Allow unsigned integers, which have special; TSCAL/TZERO values. Feb 2009;;-; compile_opt idl2@fxbintable ON_ERROR, 2;; Check the number of parameters.; IF N_PARAMS() LT 2 THEN BEGIN MESSAGE = 'Syntax: FXBWRITM, UNIT, COL, DATA1, DATA2, ' $ +' ..., ROW=, POINTERS=, PASS_METHOD=, NANVALUE=, BUFFERSIZE=' IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF IF N_ELEMENTS(BUFFERSIZE) EQ 0 THEN BUFFERSIZE = 32768L;; COL may be one of several descriptors:; * a list of column numbers, beginning with 1; * a list of column names; MYCOL = [ COL ] ; Make sure it is an array SC = SIZE(MYCOL) NUMCOLS = N_ELEMENTS(MYCOL) OUTSTATUS = LONARR(NUMCOLS) COLNAMES = 'D'+STRTRIM(LINDGEN(50),2);; Determine whether the data has been passed as arguments or pointers; IF N_ELEMENTS(PASS_METHOD) EQ 0 THEN PASS_METHOD = 'ARGUMENT' PASS = STRUPCASE(STRTRIM(PASS_METHOD[0],2)) IF PASS NE 'ARGUMENT' AND PASS NE 'POINTER' THEN BEGIN MESSAGE = 'ERROR: PASS_METHOD must be ARGUMENT or POINTER' IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF NP = N_ELEMENTS(POINTERS) IF PASS NE 'ARGUMENT' AND NP LT NUMCOLS THEN BEGIN MESSAGE = 'ERROR: POINTERS array contains too few elements' IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF IF PASS EQ 'POINTER' THEN BEGIN SZ = SIZE(POINTERS) IF SZ[SZ[0]+1] NE 10 THEN BEGIN MESSAGE = 'ERROR: POINTERS must be an array of pointers' IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF WH = WHERE(PTR_VALID(POINTERS[0:NUMCOLS-1]) EQ 0, CT) IF CT GT 0 THEN BEGIN MESSAGE = 'ERROR: POINTERS contains invalid pointers' IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF ENDIF ;; Find the logical unit number in the FXBINTABLE common block.; 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;; 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;; Check the number of columns. It should be fewer than 50; IF (NUMCOLS GT 50) AND (PASS EQ 'ARGUMENT') THEN BEGIN MESSAGE = 'Maximum of 50 columns exceeded' IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF; Commented out because too much data is not a problem; IF NUMCOLS LT N_PARAMS()-2 THEN BEGIN; MESSAGE = 'ERROR: too few data parameters passed'; IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN; ERRMSG = MESSAGE; RETURN; END ELSE MESSAGE, MESSAGE; ENDIF ICOL = LONARR(NUMCOLS) FOUND = BYTARR(NUMCOLS) NOTFOUND = '' NNOTFOUND = 0L IF N_ELEMENTS(WARNMSG) NE 0 THEN WARNMSG = '';; If COL is of type string, then search for a column with that label.; IF SC[SC[0]+1] EQ 7 THEN BEGIN MYCOL = STRUPCASE(STRTRIM(MYCOL,2)) FOR I = 0, NUMCOLS-1 DO BEGIN XCOL = WHERE(TTYPE[*,ILUN] EQ MYCOL[I], NCOL) ICOL[I] = XCOL[0] IF NCOL GT 0 THEN FOUND[I] = 1 IF NOT FOUND[I] THEN BEGIN IF NOTFOUND EQ '' THEN NOTFOUND = MYCOL[I] $ ELSE NOTFOUND = NOTFOUND +', ' + MYCOL[I] NNOTFOUND = NNOTFOUND + 1 ENDIF ENDFOR IF NNOTFOUND EQ NUMCOLS THEN BEGIN MESSAGE = 'ERROR: None of the requested columns were found' IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF ELSE IF NNOTFOUND GT 0 THEN BEGIN MESSAGE = 'WARNING: Columns ' + NOTFOUND + ' were not found' IF N_ELEMENTS(WARNMSG) NE 0 THEN WARNMSG = MESSAGE $ ELSE MESSAGE, MESSAGE, /INFO ENDIF;; Otherwise, a numerical column was passed. Check its value.; ENDIF ELSE BEGIN ICOL[*] = LONG(MYCOL) - 1 FOUND[ICOL] = 1 ENDELSE ;; Step through each column index, and check for validity; MESSAGE = '' FOR I = 0, NUMCOLS-1 DO BEGIN IF NOT FOUND[I] THEN GOTO, LOOP_END_COLCHECK IF (ICOL[I] LT 0) OR (ICOL[I] GE TFIELDS[ILUN]) THEN BEGIN MESSAGE = 'COL "'+STRTRIM(MYCOL[I],2)+$ '" must be between 1 and ' + $ STRTRIM(TFIELDS[ILUN],2) FOUND[I] = 0 ENDIF;; If there are no elements in the array, then set !ERR to -1.; IF FOUND[I] AND N_ELEM[ICOL[I],ILUN] EQ 0 THEN BEGIN FOUND[I] = 0 MESSAGE = MESSAGE + '; Number of elements to write in "'+$ STRTRIM(MYCOL[I],2)+'" should be zero' ENDIF;; Do not permit variable-length columns; IF MAXVAL[ICOL[I],ILUN] GT 0 THEN BEGIN MESSAGE = MESSAGE + 'FXBWRITM cannot write ' + $ 'variable-length column "'+STRTRIM(MYCOL[I],2)+'"' FOUND[I] = 0 ENDIF LOOP_END_COLCHECK: ENDFOR;; If ROW was not passed, then set it equal to the entire range. Otherwise,; extract the range.; IF N_ELEMENTS(ROW) EQ 0 THEN BEGIN ROW = [1L, NAXIS2[ILUN]] ENDIF CASE N_ELEMENTS(ROW) OF 1: ROW2 = LONG(ROW[0]) 2: ROW2 = LONG(ROW[1]) ELSE: BEGIN MESSAGE = 'ROW must have one or two elements'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -