pro read_princeton_gz, file, $ data, $ compress=compress, $ nodata = nodata, $ header=header, $ x_calibration=x_calibration, $ y_calibration=y_calibration, $ comments=comments, $ exposure=exposure, $ background_file = background_file, $ date=date, $ assoc=assoc, $ lun=lun ;+ ; NAME: ; READ_PRINCETON_GZ ; ; PURPOSE: ; This procedure reads data files written by Princeton Instruments' ; WinSPEC and WinVIEW software. ; ; CATEGORY: ; File input. ; ; CALLING SEQUENCE: ; READ_PRINCETON, File, Data ; ; INPUTS: ; File: ; The name of the data file to read. ; ; KEYWORD INPUTS: ; compress=compress ; 0 if uncompressed, 1 if compressed (see compress keyword to open) ; -1 to determine compression from the filename ; nodata = nodata ; 1 if routine should read the header only ; ; OUTPUTS: ; Data[nx, ny, nframes]: ; The output data array. The array will be 1, 2 or 3 dimensions ; (depending upon whether ny and nframes are 1) and can be integer, ; long or float data type. ; ; KEYWORD OUTPUTS: ; HEADER: ; The 4100 byte header from the file. This header can be used to ; extract additional information about the file. See the Princteon ; Instruments "PC Interface Library Programming Manual" for the ; description of the header structure, and this procedure for ; examples of how to extract information from the header. ; ; X_CALIBRATION: ; An nx array of calibrated values for each pixel in the X direction. ; Y_CALIBRATION: ; An ny array of calibrated values for each pixel in the Y direction. ; COMMENTS: ; A 5-element string array containing the "experiment comments" ; fields, which is a 5x80 byte array starting at location 200 in ; the PI header. These fields are typically used to store ; experiment-specific information. For example, in the tomography ; experiments we use the first two strings to store the frame type ; and rotation angle. ; DATE: ; A date string of the form DDMMMYYYY:HH:MM:SS ; EXPOSURE: ; The exposure time in seconds. ; BACKGROUND_FILE: ; The name of the background file that was subtracted from the data ; ; RESTRICTIONS: ; This procedure currently only extracts limited information from the ; header. It should be exhanced to extract more fields, probably into a ; structure. ; The data and calibration are corrected for byte order when reading on ; a big-endian host, but other elements of the header are not converted. ; ; EXAMPLE: ; Read a data file: ; ; IDL> READ_PRINCETON, 'test.spe', data, header=header, x_cal=x_cal ; IDL> plot, x_cal, data ; IDL> clock_speed = float(header, 1428) ; IDL> print, 'Vertical clock speed (microseconds) = ', clock_speed ; ; MODIFICATION HISTORY: ; Written by: Mark Rivers, 11/4/97 ; Mark Rivers 10/27/98 Convert data to long if any pixels are > 32K ; Mark Rivers 11/12/98 Fix to not convert data if already long ; Mark Rivers 3/16/99 Added /BLOCK keyword to openr to work with VMS ; Mark Rivers 3/27/99 Added "Comments" keyword ; Mark Rivers 3/29/99 Added "Date" keyword ; Mark Rivers 2/22/00 Corrected byte order for data and calibration. ; Mark Rivers 9/11/01 Added "exposure" keyword ; Mark Rivers 9/12/01 Added "background_file" keyword ; ; Leslie Young (Southwest Research Institute) 08/05/07 ; changed name to read_princeton_gz ; - allows reading of gzipped files ; - calls convert_princeton_header2 for more complete interpretation ; of header ; - added nodota input keyword ;- if keyword_set(compress) then begin if compress eq -1 then begin compress_local = (strmatch(file,'*gz', /fol))[0] endif else begin compress_local = compress endelse endif else begin if n_elements(compress) eq 0 then begin compress_local = (strmatch(file,'*gz', /fol))[0] endif else begin compress_local = 0 endelse endelse openr, lun, /get, file, /block, compress=compress_local header = bytarr(4100) readu, lun, header ; Convert the header from a byte array to a structure header = convert_princeton_header2(header) ; Get the image size from the header nx = header.xdim ny = header.ydim nframes = header.NumFrames data_type = header.datatype xcal = header.xcalibration ycal = header.ycalibration order = xcal.polynoorder < (n_elements(xcal.polynocoeff) - 1) x_calibration = poly(findgen(nx), xcal.polynocoeff[0:order]) order = ycal.polynoorder < (n_elements(ycal.polynocoeff) - 1) y_calibration = poly(findgen(ny), ycal.polynocoeff[0:order]) ;x_calibration = poly(findgen(nx), xcal.polynocoeff(0:xcal.polynoorder)) ;y_calibration = poly(findgen(ny), ycal.polynocoeff(0:ycal.polynoorder)) comments=header.comments comments=string(comments) date = header.date ;hour = fix(header, 30) ;byteorder, hour, /sswap, /swap_if_big_endian ;minute = fix(header, 32) ;byteorder, minute, /sswap, /swap_if_big_endian ;second = fix(header, 38) ;byteorder, second, /sswap, /swap_if_big_endian ;date = date + ":" + string(hour, format='(i2.2)') $ ; + ":" + string(minute, format='(i2.2)') $ ; + ":" + string(second, format='(i2.2)') exposure = header.exp_sec if (header.BackGrndApplied) then background_file = header.background $ else background_file = "" if keyword_set(nodata) then begin data = -1 close, lun & free_lun, lun return endif if keyword_set(assoc) then begin close, lun & free_lun, lun if compress_local eq 1 then begin message, 'Cannot use assoc with compressed files' data = -1 return endif openr, lun, /get, file, /swap_if_big_endian case data_type of ; 0: data = assoc(lun, fltarr(nx, ny, nframes, /noz), 4100) ; 1: data = assoc(lun, lonarr(nx, ny, nframes, /noz), 4100) ; 2: data = assoc(lun, intarr(nx, ny, nframes, /noz), 4100) ; 3: data = assoc(lun, uintarr(nx, ny, nframes, /noz), 4100) 0: data = assoc(lun, fltarr(nx, ny, /noz), 4100) 1: data = assoc(lun, lonarr(nx, ny, /noz), 4100) 2: data = assoc(lun, intarr(nx, ny, /noz), 4100) 3: data = assoc(lun, uintarr(nx, ny, /noz), 4100) else: begin message, 'Unknown data type' data = -1 end endcase return endif else begin case data_type of 0: data = fltarr(nx, ny, nframes) 1: data = lonarr(nx, ny, nframes) 2: data = intarr(nx, ny, nframes) 3: data = uintarr(nx, ny, nframes) else: message, 'Unknown data type' endcase readu, lun, data data = reform(data) ; Eliminate trailing dimensions if 1 case data_type of 0: byteorder, data, /lswap, /swap_if_big_endian 1: byteorder, data, /lswap, /swap_if_big_endian 2: byteorder, data, /sswap, /swap_if_big_endian 3: byteorder, data, /sswap, /swap_if_big_endian else: message, 'Unknown data type' endcase close, lun & free_lun, lun endelse end