📄 readfits.pro
字号:
; Read the next header, and get the number of bytes taken up by the data. block = string(replicate(32b,80,36)) w = [-1] if ((ext EQ exten_no) and (doheader)) then header = strarr(hbuf) $ else header = strarr(36) headerblock = 0L i = 0L while w[0] EQ -1 do begin if EOF(unit) then begin message,/ CON, $ 'EOF encountered attempting to read extension ' + strtrim(ext,2) if not unitsupplied then free_lun,unit return,-1 endif readu, unit, block headerblock = headerblock + 1 w = where(strlen(block) NE 80, Nbad) if (Nbad GT 0) then begin message,'Warning-Invalid characters in header',/INF,NoPrint=Silent block[w] = string(replicate(32b, 80)) endif w = where(strmid(block, 0, 8) eq 'END ', Nend) if (headerblock EQ 1) or ((ext EQ exten_no) and (doheader)) then begin if Nend GT 0 then begin if headerblock EQ 1 then header = block[0:w[0]] $ else header = [header[0:i-1],block[0:w[0]]] endif else begin header[i] = block i = i+36 if i mod hbuf EQ 0 then $ header = [header,strarr(hbuf)] endelse endif endwhile if (ext EQ 0 ) and (keyword_set(pointlun) EQ 0) then $ if strmid( header[0], 0, 8) NE 'SIMPLE ' then begin message,/CON, $ 'ERROR - Header does not contain required SIMPLE keyword' if not unitsupplied then free_lun, unit return, -1 endif ; Get parameters that determine size of data region. bitpix = sxpar(header,'BITPIX') naxis = sxpar(header,'NAXIS') gcount = sxpar(header,'GCOUNT') > 1 pcount = sxpar(header,'PCOUNT') if naxis GT 0 then begin dims = sxpar( header,'NAXIS*') ;Read dimensions ndata = long64(dims[0]) if naxis GT 1 then for i = 2, naxis do ndata = ndata*dims[i-1] endif else ndata = 0 nbytes = (abs(bitpix) / 8) * gcount * (pcount + ndata); Move to the next extension header in the file. Use MRD_SKIP to skip with; fastest available method (POINT_LUN or readu) for different file; types (regular, compressed, Unix pipe, socket) if ext LT exten_no then begin nrec = long((nbytes + 2879) / 2880) if nrec GT 0 then mrd_skip, unit, nrec*2880L endif endfor case BITPIX of 8: IDL_type = 1 ; Byte 16: IDL_type = 2 ; Integer*2 32: IDL_type = 3 ; Integer*4 64: IDL_type = 14 ; Integer*8 -32: IDL_type = 4 ; Real*4 -64: IDL_type = 5 ; Real*8 else: begin message,/CON, 'ERROR - Illegal value of BITPIX (= ' + $ strtrim(bitpix,2) + ') in FITS header' if not unitsupplied then free_lun,unit return, -1 end endcase ; Check for dummy extension header if Naxis GT 0 then begin Nax = sxpar( header, 'NAXIS*' ) ;Read NAXES ndata = long64(nax[0]) ;Updated Jan 2009 if naxis GT 1 then for i = 2, naxis do ndata = ndata*nax[i-1] endif else ndata = 0 nbytes = (abs(bitpix)/8) * gcount * (pcount + ndata) if nbytes EQ 0 then begin if not SILENT then message, $ "FITS header has NAXIS or NAXISi = 0, no data array read",/CON if do_checksum then begin result = FITS_TEST_CHECKSUM(header, data, ERRMSG = errmsg) if not SILENT then begin case result of 1: message,/INF,'CHECKSUM keyword in header is verified' -1: message,/CON, errmsg else: endcase endif endif if not unitsupplied then free_lun, unit return,-1 endif; Check for FITS extensions, GROUPS groups = sxpar( header, 'GROUPS' ) if groups then message,NoPrint=Silent, $ 'WARNING - FITS file contains random GROUPS', /INF; If an extension, did user specify row to start reading, or number of rows; to read? if not keyword_set(STARTROW) then startrow = 0 if naxis GE 2 then nrow = nax[1] else nrow = ndata if not keyword_set(NUMROW) then numrow = nrow if do_checksum then if ((startrow GT 0) or $ (numrow LT nrow) or (N_elements(nslice) GT 0)) then begin message,/CON, $ 'Warning - CHECKSUM not applied when STARTROW, NUMROW or NSLICE is set' do_checksum = 0 endif if exten_no GT 0 then begin xtension = strtrim( sxpar( header, 'XTENSION' , Count = N_ext),2) if N_ext EQ 0 then message, /INF, NoPRINT = Silent, $ 'WARNING - Header missing XTENSION keyword' endif if (exten_no GT 0) and ((startrow NE 0) or (numrow NE nrow)) then begin if startrow GE nax[1] then begin message,'ERROR - Specified starting row ' + strtrim(startrow,2) + $ ' but only ' + strtrim(nax[1],2) + ' rows in extension',/CON if not unitsupplied then free_lun,unit return,-1 endif nax[1] = nax[1] - startrow nax[1] = nax[1] < numrow sxaddpar, header, 'NAXIS2', nax[1] if startrow GT 0 then mrd_skip, unit, startrow*nax[0] endif else if (N_elements(NSLICE) EQ 1) then begin lastdim = nax[naxis-1] if nslice GE lastdim then message,/CON, $ 'ERROR - Value of NSLICE must be less than ' + strtrim(lastdim,2) nax = nax[0:naxis-2] sxdelpar,header,'NAXIS' + strtrim(naxis,2) naxis = naxis-1 sxaddpar,header,'NAXIS',naxis ndata = ndata/lastdim nskip = long64(nslice)*ndata*abs(bitpix/8) if Ndata GT 0 then mrd_skip, unit, nskip endif if not (SILENT) then begin ;Print size of array being read if exten_no GT 0 then message, $ 'Reading FITS extension of type ' + xtension, /INF st = 'Now reading ' + strjoin(strtrim(NAX,2),' by ') + ' array' if (exten_no GT 0) and (pcount GT 0) then st = st + ' + heap area' message,/INF,st endif; Read Data in a single I/O call. Only need byteswapping for Unix compress; files data = make_array( DIM = nax, TYPE = IDL_type, /NOZERO) readu, unit, data if unixZ then swap_endian_inplace,data,/swap_if_little if (exten_no GT 0) and (pcount GT 0) then begin theap = sxpar(header,'THEAP') skip = theap - N_elements(data) if skip GT 0 then begin temp = bytarr(skip,/nozero) readu, unit, skip endif heap = bytarr(pcount*gcount*abs(bitpix)/8) readu, unit, heap if do_checksum then $ result = fits_test_checksum(header,[data,heap],ERRMSG=errmsg) endif else if do_checksum then $ result = fits_test_checksum(header, data, ERRMSG = errmsg) if not unitsupplied then free_lun, unit if do_checksum then if not SILENT then begin case result of 1: message,/INF,'CHECKSUM keyword in header is verified' -1: message,/CON, 'CHECKSUM ERROR! ' + errmsg else: endcase endif; Scale data unless it is an extension, or /NOSCALE is set; Use "TEMPORARY" function to speed processing. do_scale = not keyword_set( NOSCALE ) if (do_scale and (exten_no GT 0)) then do_scale = xtension EQ 'IMAGE' if do_scale then begin Nblank = 0 if bitpix GT 0 then begin blank = sxpar( header, 'BLANK', Count = N_blank) if N_blank GT 0 then $ blankval = where( data EQ blank, Nblank) endif Bscale = sxpar( header, 'BSCALE' , Count = N_bscale) Bzero = sxpar(header, 'BZERO', Count = N_Bzero ) ; Check for unsigned integer (BZERO = 2^15) or unsigned long (BZERO = 2^31) if not keyword_set(No_Unsigned) then begin no_bscale = (Bscale EQ 1) or (N_bscale EQ 0) unsgn_int = (bitpix EQ 16) and (Bzero EQ 32768) and no_bscale unsgn_lng = (bitpix EQ 32) and (Bzero EQ 2147483648) and no_bscale unsgn = unsgn_int or unsgn_lng endif else unsgn = 0 if unsgn then begin if unsgn_int then $ data = uint(data) - 32768US else $ if unsgn_lng then data = ulong(data) - 2147483648UL sxaddpar, header, 'BSCALE', 1. sxaddpar, header, 'O_BSCALE', Bscale,' Original BSCALE Value' endif else begin if N_Bscale GT 0 then $ if ( Bscale NE 1. ) then begin if size(Bscale,/TNAME) NE 'DOUBLE' then $ data = temporary(data) * float(Bscale) else $ data = temporary(data) * Bscale sxaddpar, header, 'BSCALE', 1. sxaddpar, header, 'O_BSCALE', Bscale,' Original BSCALE Value' sxaddpar, header, 'BZERO', 0. sxaddpar, header, 'O_BZERO', Bzero,' Original BZERO Value' endif if N_Bzero GT 0 then $ if (Bzero NE 0) then begin if size(Bzero,/TNAME) NE 'DOUBLE' then $ data = temporary( data ) + float(Bzero) else $ ;Fixed Aug 07 data = temporary( data ) + Bzero sxaddpar, header, 'BZERO', 0. sxaddpar, header, 'O_BZERO', Bzero,' Original BZERO Value' endif endelse if (Nblank GT 0) and ((N_bscale GT 0) or (N_Bzero GT 0)) then $ data[blankval] = blank endif; Return array. If necessary, first convert NaN values. if n_elements(nanvalue) eq 1 then begin w = where(finite(data,/nan),count) if count gt 0 then data[w] = nanvalue endif return, data ; Come here if there was an IO_ERROR BAD: print,!ERROR_STATE.MSG if (not unitsupplied) and (N_elements(unit) GT 0) then free_lun, unit if N_elements(data) GT 0 then return,data else return, -1 end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -