;+ ; NAME: ; hstpsf ; PURPOSE: (one line) ; Find or create a HST PSF file using Tiny Tim. ; DESCRIPTION: ; See Tiny Tim User's Manual, Version 2.4, for details. ; CATEGORY: ; Miscellaneous ; CALLING SEQUENCE: ; hstpsf, x, y, date, filter, bmvnum, psf, xmax, ymax ; INPUTS: ; x, y : Chip position. ; date : Date of observation (YYMMDD format). ; filter : Filter name in the form Fxxx(W,LP,M,N). ; bmvnum : B-V list value: ; 1) -0.297 (Type O) ; 2) -0.155 (Type B) ; 3) 0.126 (Type A) ; 4) 0.395 (Type F) ; 5) 0.619 (Type G) ; 6) 1.110 (Type K) ; 7) 1.590 (Type M) ; OPTIONAL INPUT PARAMETERS: ; ; KEYWORD PARAMETERS: ; FLUSH = If set, flushes the local cache before begining PSF search. ; GRID = Grid spacing for nearest PSF location. Default=50 pixels. ; HSTPATH = The starting directory path for the location of the PSF'S. ; Used, primarily, for maintenance. ; VERBOSE = If set, displays informational messages. ; ; OUTPUTS: ; psf : The generated PSF array. ; xmax : Interpolated maximum x-location. ; ymax : Interpolated maximum y-location. ; ; COMMON BLOCKS: ; hstpsf_com : Local. Holds one copy of a PSF array and its full name. ; SIDE EFFECTS: ; ; RESTRICTIONS: ; Presently, only the Planetary Camera, Chip 6 (P6), and filters F555W ; and F439W are supported. ; This version generates PSF'S with 7.5 micron spacing (2X over-sampling) ; and 5 arcsecond diameters. ; PROCEDURE: ; A nearest grid position is computed from the input chip position using the ; specified, or default, grid spacing. ; If a PSF has been previously computed at that grid position (matching the ; other input parameters), that file is loaded into the caller's array. ; Otherwise, a new PSF is created, placed into the appropriate ; sub-directory, and loaded into the caller's array.. ; ; MODIFICATION HISTORY: ; Written by Doug Loucks, Lowell Observatory, August, September, 1993. ; 12/1/93, DWL, Modified to work with Tiny Tim Version 2.4. ; 12/9/93, DWL, Modified to hold one copy of a PSF in common. If the ; requested PSF is the same as that in common, a disk-access is avoided and ; the memory copy is returned. ; 12/16/93, DWL, Added VERBOSE keyword. If set, displays informational ; messages. ; 1/12/94, DWL, Added cache for two psf's. ; 1/21/94, DWL, Added cache for n psf's. See local variable ncache. ; 1/21/94, DWL, Added code to compuite and store each psf's interpolated ; maximum. Also, added FLUSH keyword. ;- PRO hstpsf, in_x, in_y, in_date, in_filter, in_bmvnum, $ out_psf, out_xm, out_ym, $ FLUSH=in_flush, GRID=in_grid, HSTPATH=in_mainpath, $ VERBOSE=in_verbose COMMON hstpsf_com, save_indx, save_name, save_psf, save_max IF N_PARAMS() EQ 0 THEN BEGIN PRINT, 'hstpsf, x, y, date, filter, bmvnum, psf, xmax, ymax' RETURN ENDIF ;Verify proper input parameter types. self = '% HSTPSF: ' IF badpar( in_x, [2,3,4,5], 0, CALLER=self+'(x) ' ) THEN RETURN IF badpar( in_y, [2,3,4,5], 0, CALLER=self+'(y) ' ) THEN RETURN IF badpar( in_date, 7, 0, CALLER=self+'(date) ' ) THEN RETURN IF badpar( in_filter, 7, 0, CALLER=self+'(filter) ' ) THEN RETURN IF badpar( in_bmvnum, 2, 0, CALLER=self+'(bmvnum) ' ) THEN RETURN ;Set grid size. IF KEYWORD_SET( in_grid ) THEN BEGIN IF badpar( in_grid, 2, 0, CALLER=self ) THEN RETURN grid = in_grid ENDIF ELSE BEGIN grid = 50 ENDELSE ;Set the main path for all of the PSF files. IF KEYWORD_SET( in_mainpath ) THEN BEGIN IF badpar( in_mainpath, 7, 0, CALLER=self ) THEN RETURN mainpath=in_mainpath ENDIF ELSE BEGIN mainpath = '/gryll/data2/hstpsf/' ENDELSE l = STRLEN( mainpath ) IF STRMID( mainpath, l-1, 1 ) NE '/' THEN mainpath=mainpath+'/' ;******************* Variables which might be edited ********************* ;Planetary camera. camera = '2' ;Planetary Camera chip number. chip = '6' ;PSF size, in arcseconds. psfsize = '5' ;PSF size, in pixels. psfdim = 232 ;Oversample factor. sampfact = '2' ;Number of local memory slots for cached psf's. ncache = 3 ;*************************************************************************** ;Compute the nearest grid position. x = nint( FLOAT(in_x) / grid ) * grid y = nint( FLOAT(in_y) / grid ) * grid ;Need string versions of the position to form the PSF filename. sx = STRTRIM( STRING( x ), 2 ) sy = STRTRIM( STRING( y ), 2 ) IF KEYWORD_SET( in_verbose ) THEN BEGIN ;Display the input and the grid positions. MESSAGE, 'Input position: ' + STRING(in_x, in_y, FORMAT='(2F12.4)'), /INFO MESSAGE, 'Grid position: ' + STRING( x, y, FORMAT='(2I12)' ), /INFO ENDIF ;Put date into format required by Tiny Tim. date = STRMID( in_date, 4, 2 ) + ' ' + STRMID( in_date, 2, 2 ) + $ ' 19' + STRMID( in_date, 0, 2 ) ;Force upper case filter name. filter = STRUPCASE( in_filter ) ;Need string version of B-V list value for sub-directory name. bmvstr = STRTRIM( STRING( in_bmvnum ), 2 ) ;No jitter, thank you. jitter = 'n' ;Want FITS format. fmt = 'f' ;Rootname. rootname = 'temp' outstr = [ 'tiny1 temp.par << EOI', $ camera, chip, sx+' '+sy, date, filter, bmvstr, psfsize, $ 'y', sampfact, jitter, fmt, rootname, 'EOI' ] ;Make the intermediate directory name strings. datedir = in_date + '/' filterdir = filter + '/' bmvdir = bmvstr + '/' ;Form the PSF filename. psf = sx + '_' + sy + '.fit' psm = sx + '_' + sy + '.max' ;Form the full path. path = mainpath + datedir + filterdir + bmvdir ;Check for first call. stat = SIZE( save_indx ) IF ((stat[0] EQ 0) AND (stat[1] EQ 0)) OR (KEYWORD_SET(in_flush)) THEN BEGIN save_indx = 0 save_name = STRARR( ncache ) save_max = FLTARR( 2, ncache ) save_psf = FLTARR( psfdim, psfdim, ncache ) ENDIF w = WHERE( save_name EQ path+psf, count ) IF count EQ 1 THEN BEGIN ;The requested psf is in cache. w = w[0] IF KEYWORD_SET( in_verbose ) THEN MESSAGE, $ 'Loading ' + save_name[w] + ' from cache.', /INFO out_psf = save_psf[*,*,w] out_xm = save_max[0,w] out_ym = save_max[1,w] RETURN ENDIF IF exists( path + psf ) THEN BEGIN ;The requested psf is on disk. save_name[ save_indx ] = path + psf IF KEYWORD_SET( in_verbose ) THEN MESSAGE, $ 'Loading ' + save_name[ save_indx ] + ' from disk.', /INFO save_psf[*,*,save_indx] = READFITS( path + psf, /SILENT ) out_psf = save_psf[*,*,save_indx] IF exists( path + psm ) THEN BEGIN ;The interpolated maximum save file can be read. xm = 0.0 ym = 0.0 GET_LUN, lu OPENR, lu, path+psm READF, lu, xm, ym CLOSE, lu FREE_LUN, lu ENDIF ELSE BEGIN ;Need to compute the interpolated maximum. IF KEYWORD_SET( in_verbose ) THEN MESSAGE, $ 'Computing interpolated maximum...', /INFO boxm, out_psf, psfdim/2, psfdim/2, 10, 10, xmax, ymax findmax, xmax, ymax, out_psf, xm, ym, fm GET_LUN, lu OPENW, lu, path+psm PRINTF, lu, xm, ym CLOSE, lu FREE_LUN, lu ENDELSE out_xm = xm out_ym = ym save_max[ *, save_indx ] = [ xm, ym ] save_indx = ( save_indx + 1 ) MOD ncache RETURN ENDIF ;At this point, it will be necessary to generate a new psf using Tiny Tim. ;Search the directories. If a required sub-directory does not exist, create it. SPAWN, 'ls -F ' + mainpath, hstpsfdirs i = WHERE( hstpsfdirs EQ datedir, count ) IF count EQ 0 THEN BEGIN SPAWN, 'mkdir ' + mainpath + datedir SPAWN, 'chmod 777 ' + mainpath + datedir ENDIF SPAWN, 'ls -F ' + mainpath + datedir, fdirs j = WHERE( fdirs EQ filterdir, count ) IF count EQ 0 THEN BEGIN SPAWN, 'mkdir ' + mainpath + datedir + filterdir SPAWN, 'chmod 777 ' + mainpath + datedir + filterdir ENDIF SPAWN, 'ls -F ' + mainpath + datedir + filterdir, bdirs j = WHERE( bdirs EQ bmvdir, count ) IF count EQ 0 THEN BEGIN SPAWN, 'mkdir ' + mainpath + datedir + filterdir + bmvdir SPAWN, 'chmod 777 ' + mainpath + datedir + filterdir + bmvdir ENDIF ;First, create the C-Shell file. n = N_ELEMENTS( outstr ) GET_LUN, lu OPENW, lu, 'temp.csh', ERROR=err IF err NE 0 THEN BEGIN FREE_LUN, lu MESSAGE, !error_state.msg RETURN ENDIF FOR j = 0, n-1 DO BEGIN PRINTF, lu, outstr[ j ] ENDFOR CLOSE, lu FREE_LUN, lu ;Then spawn the process to invoke the C-Shell file. SPAWN, 'csh temp.csh', result ;Then spawn the process to invoke tiny2. SPAWN, 'tiny2 temp.par' ; Finally, spawn a process to erase the temporary files. SPAWN, 'rm -f temp.csh temp.par temp.lis' IF exists( 'temp00.fit' ) THEN BEGIN SPAWN, 'mv temp00.fit ' + path + psf SPAWN, 'chmod 666 ' + path + psf ENDIF ;Check that the Tiny Tim run was successful. IF exists( path + psf ) THEN BEGIN ;Load the requested PSF. save_name[ save_indx ] = path + psf IF KEYWORD_SET( in_verbose ) THEN MESSAGE, $ 'Loading ' + save_name[ save_indx ] + ' from disk.', /INFO out_psf = READFITS( path + psf, /SILENT ) save_psf[*,*,save_indx] = out_psf ;Compute and save the interpolated maximum. boxm, out_psf, psfdim/2, psfdim/2, 10, 10, xmax, ymax findmax, xmax, ymax, out_psf, xm, ym, fm GET_LUN, lu OPENW, lu, path+psm PRINTF, lu, xm, ym CLOSE, lu FREE_LUN, lu out_xm = xm out_ym = ym save_max[*, save_indx ] = [ xm, ym ] save_indx = ( save_indx + 1 ) MOD ncache ENDIF ELSE BEGIN ;Set output to indicate something failed. out_psf = -1 MESSAGE, 'Error. PSF not created.', /INFO RETURN ENDELSE END