📄 fxbreadm.pro
字号:
;; Determine whether the data is to be extracted as pointers or arguments; 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 EQ 'POINTER' THEN BEGIN IF NP EQ 0 THEN POINTERS = PTRARR(NUMCOLS, /ALLOCATE_HEAP) NP = N_ELEMENTS(POINTERS) 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;; Expand the pointer array if necessary; IF NP LT NUMCOLS THEN $ POINTERS = [POINTERS[*], PTRARR(NUMCOLS-NP, /ALLOCATE_HEAP)] NP = N_ELEMENTS(POINTERS);; Make sure there are no null pointers, which cannot be assigned to.; WH = WHERE(PTR_VALID(POINTERS) EQ 0, CT) IF CT GT 0 THEN POINTERS[WH] = PTRARR(CT, /ALLOCATE_HEAP) 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;; Check the number of columns. It should be fewer than 49; IF PASS EQ 'ARGUMENT' THEN BEGIN IF NUMCOLS GT 49 THEN BEGIN MESSAGE = 'Maximum of 49 columns exceeded' IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF IF N_PARAMS()-2 LT NUMCOLS AND N_ELEMENTS(ERRMSG) EQ 0 THEN BEGIN MESSAGE, 'WARNING: number of data parameters less than columns', $ /INFO ENDIF ENDIF ICOL = LONARR(NUMCOLS) VIRTUAL = BYTARR(NUMCOLS) VIRTYPE = LONARR(NUMCOLS) FOUND = BYTARR(NUMCOLS) VARICOL = 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 the column was not found, and VIRTUAL was set, then search for a keyword; by that name.; IF NCOL GT 0 THEN FOUND[I] = 1 IF NOT FOUND[I] AND KEYWORD_SET(VIR) THEN BEGIN HEADER = HEAD[*,ILUN] VALUE = FXPAR(HEADER,MYCOL[I], Count = N_VALUE) IF N_VALUE GE 0 THEN BEGIN RESULT = EXECUTE(COLNAMES[I]+' = VALUE') SV = SIZE(VALUE) VIRTYPE[I] = SV[SV[0]+1] VIRTUAL[I] = 1 FOUND[I] = 1 ENDIF ENDIF ELSE 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[*] = 1 ENDELSE; Step through each column index MESSAGE = '' FOR I = 0, NUMCOLS-1 DO BEGIN IF NOT FOUND[I] THEN GOTO, LOOP_END_COLCHECK IF VIRTUAL[I] THEN GOTO, LOOP_END_COLCHECK IF (ICOL[I] LT 0) OR (ICOL[I] GE TFIELDS[ILUN]) THEN BEGIN MESSAGE = 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 read in "'+$ STRTRIM(MYCOL[I],2)+'" is zero'; !ERR = -1; RETURN ENDIF;; Flag variable-length columns; IF MAXVAL[ICOL[I],ILUN] GT 0 THEN BEGIN FOUND[I] = 1 VARICOL[I] = 1 ENDIF LOOP_END_COLCHECK: ENDFOR;; Check to be sure that there are columns to be read; W = WHERE(FOUND EQ 1, COUNT) WV = WHERE(FOUND EQ 1 OR VARICOL EQ 1, WVCOUNT) IF WVCOUNT EQ 0 THEN BEGIN STRPUT, MESSAGE, ':', 0 MESSAGE = 'ERROR: No requested columns could be read'+MESSAGE IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF ELSE IF MESSAGE NE '' THEN BEGIN STRPUT, MESSAGE, ':', 0 MESSAGE = 'WARNING: Some columns could not be read'+MESSAGE IF N_ELEMENTS(WARNMSG) NE 0 THEN WARNMSG = MESSAGE $ ELSE MESSAGE, MESSAGE, /INFO ENDIF ;; If ROW was not passed, then set it equal to the entire range. Otherwise,; extract the range.; IF N_ELEMENTS(ROW) EQ 0 THEN ROW = [1L, NAXIS2[ILUN]] 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' IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE END ENDCASE ROW1 = LONG(ROW[0]);; If ROW represents a range, then make sure that the row range is legal, and; that reading row ranges is allowed (i.e., the column is not variable length.; IF ROW1 NE ROW2 THEN BEGIN MAXROW = NAXIS2[ILUN] IF (ROW1 LT 1) OR (ROW1 GT MAXROW) THEN BEGIN MESSAGE = 'ROW[0] must be between 1 and ' + $ STRTRIM(MAXROW,2) IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE END ELSE IF (ROW2 LT ROW1) OR (ROW2 GT MAXROW) THEN BEGIN MESSAGE = 'ROW[1] must be between ' + $ STRTRIM(ROW1,2) + ' and ' + STRTRIM(MAXROW,2) IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF;; Otherwise, if ROW is a single number, then just make sure it's valid.; END ELSE BEGIN IF (ROW1 LT 1) OR (ROW1 GT NAXIS2[ILUN]) THEN BEGIN MESSAGE = 'ROW must be between 1 and ' + $ STRTRIM(NAXIS2[ILUN],2) IF N_ELEMENTS(ERRMSG) NE 0 THEN BEGIN ERRMSG = MESSAGE RETURN END ELSE MESSAGE, MESSAGE ENDIF ENDELSE;; Compose information about the output; COLNDIM = LONARR(NUMCOLS) COLDIM = LONARR(NUMCOLS, 20) ;; Maximum of 20 dimensions in output COLTYPE = LONARR(NUMCOLS) BOFF1 = LONARR(NUMCOLS) BOFF2 = LONARR(NUMCOLS) NROWS = ROW2-ROW1+1 FOR I = 0L, NUMCOLS-1 DO BEGIN IF NOT FOUND[I] THEN GOTO, LOOP_END_DIMS ;; Data type of the input. IF VIRTUAL[I] THEN BEGIN ; Virtual column: read from keyword itself COLTYPE[I] = VIRTYPE[I] GOTO, LOOP_END_DIMS ENDIF ELSE IF VARICOL[I] THEN BEGIN ; Variable length column: 2-element long COLTYPE[I] = 3 DIMS = [1L, 2L] ENDIF ELSE BEGIN COLTYPE[I] = IDLTYPE[ICOL[I],ILUN] DIMS = N_DIMS[*,ICOL[I],ILUN] ENDELSE NDIMS = DIMS[0] DIMS = DIMS[1:NDIMS] IF NDIMS EQ 1 AND DIMS[0] EQ 1 THEN BEGIN ;; Case of only one output element, try to return a ;; scalar. Otherwise, it is a vector equal to the ;; number of rows to be read COLNDIM[I] = 1L COLDIM[I,0] = NROWS ENDIF ELSE BEGIN COLNDIM[I] = NDIMS COLDIM[I,0:(NDIMS-1)] = DIMS IF NROWS GT 1 THEN BEGIN COLDIM[I,NDIMS] = NROWS COLNDIM[I] = COLNDIM[I]+1 ENDIF ENDELSE ;; For strings, the number of characters is the first ;; dimension. This information is useless to us now, ;; since the STRING() type cast which will appear below ;; handles the array conversion automatically. IF COLTYPE[I] EQ 7 THEN BEGIN IF COLNDIM[I] GT 1 THEN BEGIN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -