;+ ; NAME: ; smei_star_standard ; PURPOSE: ; Read in the standard star map ; CATEGORY: ; camera/idl/star ; CALLING SEQUENCE: FUNCTION smei_star_standard, camera , $ bkgnd_radius = bkgnd_radius , $ bkgnd_origin = bkgnd_origin , $ wing_radius = wing_radius , $ wing_origin = wing_origin , $ wing_delta = wing_delta , $ psfstretch = psfstretch , $ degrees = degrees , $ get_origin = get_origin , $ get_ndim = get_ndim , $ get_fov = get_fov , $ get_scale = get_scale , $ get_nomansland_id = get_nomansland_id , $ get_background_id = get_background_id , $ get_wayoutside_id = get_wayoutside_id , $ use_filled_psf = use_filled_psf , $ in_psf = in_psf , $ show = show , $ scale = scale , $ origin = origin ; INPUTS: ; camera scalar; type: integer; default: 2 ; camera number (1,2,3) ; OPTIONAL INPUT PARAMETERS: ; /degrees all angles are in degrees (default is radians) ; This includes bkgnd_radius, wing_radius, psfstretch ; bkgnd_origin and wing_origin ; bkgnd_radius=bkgnd_radius ; scalar or array[2]; type: float; default: none ; Radius of circle around centroid of standard star ; used to define the background area around the PSF ; If two radii are specified than the ring in between ; the two circles is used to define the background area ; bkgnd_origin=bkgnd_origin ; array[2]; type: float; default: [0,0] ; only used if bkgnd_radius is set. ; Shifts the origin of the ellipsoidal background area ; The units are the same as bkgnd_radius (i.e. radians or ; degrees, depending on setting of /degrees). ; wing_radius=wing_radius ; scalar or array[2]; type: float; default: none ; Axes of ellipse defining a wing area around the PSF ; If scalar then the ellipse becomes a circle. ; Inside this area the PSF is extended using an ; exponential dropoff in directions along and ; perpendicular to PSF symmetry axis. ; wing_delta=wing_delta ; scalar or array[2]; type: float; default: none ; correction to wing_radius ; wing_origin=wing_origin ; array[2]; type: float; default: [0,0] ; only used if wing_radius is set. ; Shifts the origin of the ellipsoidal wing area ; The units are the same as wing_radius (i.e. radians or ; degrees, depending on setting of /degrees). ; psfstretch=psfstretch ; array[2]; type: float: default: [0.0,0.0] ; Only used if bkgnd_radius or wing_radius is set ; to non-zero value ; Setting psfstretch to a value other than one will turn the ; background area into an ellipse with a semi-major ; axis of bkgnd_radius/psfstretch ; (usually psfstretch=cos(fovangle) where fovangle is the ; direction cosine angle in the long fov dimension) ; /get_origin if set return origin (array indices for RA=0, dec=0) of ; standard star map ; /get_ndim if set return dimensions of standard star map ; /get_fov if set return width of standard map in angular units ; This is the product of the return values for the /get_ndim ; and /get_scale keywords. ; /get_scale if set return scale (angular units per bin) of standard ; star map ; /show if set display standard star map ; OUTPUTS: ; See /get_origin, /get_scale, /get_ndim ; for return value if one of these keywords is set. If no keyword is set: ; ; std_map array[n,n]; type: float ; 2D standard star map of 200x200 bins ; map > 0 inside PSF (brightness of standard star) ; map = -1 inside inner radius, but outside PSF ; (not present if bkgnd_radius is a scalar (outer radius only) ; map = -2 inside outer radius, but outside PSF and outside ; inner radius (if specified) ; map = -3 outside outer radius, and outside PSF ; in_psf array[n,n]; type: byte ; 1 inside the non-zero area of the PSF; 0 outside ; This is the effective non-zero area of the PSF ; !!! If keyword wing_radius is set this EXCLUDES the circular ; !!! area out to radius 'wing_radius', but only covers the part ; !!! that is non-zero in the standard_star file. ; INCLUDE: @compile_opt.pro ; On error, return to caller ; COMMON BLOCKS: common smei_star_standard_save, $ std_psf , $ std_wing , $ std_cam , $ std_origin , $ std_scale , $ std_adus , $ std_map , $ std_in_psf ; CALLS: ; who_am_i, destroyvar, IsType, ToDegrees, gridgen, InitVar ; PROCEDURE: ; The standard star is stored in Fits file standard_star.fts.gz ; in the same directory as this procedure. ; The standard map is a 200x200 array covering a 5x5 deg area ; (0.025 deg/bin). for each camera. It contains positive-definite ; values defining the PSF and zero everywhere else. ; ; Either the bkgnd_* or the wing_* are used to fill the return ; array: ; ; Only outer radius specified in bkgnd_radius: ; ; The input values bkgnd_radius, bkgnd_origin and psfstretch are ; used to define an ellipsoidal area around the center of the map. ; Bins outside the ellipse are set to -3. ; Bins inside the ellipse (but not in the PSF) are set to -2. ; The output map contains -3, -2, and positive-definite values. ; ; Both inner and outer radius specified in bkgnd_radius: ; ; The input values bkgnd_radius, bkgnd_origin and psfstretch are ; used to define an ellipsoidal ring around the center of the map. ; Bins outside the outer ellipse are set to -3. ; Bins inside the ring between inner and outer ellipse ; (but not in the PSF) are set to -2. ; Bins inside the inner ellipse (but not in the PSF) are set to -1 ; The output map contains -3, -2, -1, and positive-definite values ; ; Single radius or semi-major axes specified in wing_radius: ; ; The input values wing_radius (and wing_delta), wing_origin, and ; psfstretch are used to define an ellipsoidal ring around the ; center of the map. ; Bins outside the ellipse (but not in the PSF) are set to -3. ; The output map contains -3, and positive-definite values ; ; The bins with value -2 in the output map can be used to define ; a background area around the PSF. ; MODIFICATION HISTORY: ; AUG-2006, Paul Hick (UCSD/CASS) ; AUG-2006, Paul Hick (UCSD/CASS) ; Added /use_filled_psf keyword to work with alternative PSF map ; MAR-2007, Paul Hick (UCSD/CASS) ; Change bkgnd_radius and fovxangle from argument to keyword. ; Added keywords wing_radius and wing_origin ; MAY-2007, Paul Hick (UCSD/CASS) ; Changed scalar fovxangle keyword to 2-element array psfstretch ; Changed keyword /get_adus to /get_psfadus. ; Added keyword /get_psfarea ; JUL-2007, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ; Added keyword in_psf ; Removed keywords get_psfarea and get_psfadus. ;- InitVar, use_filled_psf, /key InitVar, camera, 2 InitVar, show, /key new_psf = (['fixd','fill'])[use_filled_psf] new_wing = IsType(wing_radius,/defined) dpm = ToDegrees(degrees=degrees) ; Make sure to read proper standard map for specified camera. ; If the wrong camera map is in memory we need read another one. IF IsType(std_psf, /defined) THEN $ IF new_psf NE std_psf OR new_wing NE std_wing OR camera NE std_cam THEN $ destroyvar, std_psf IF IsType(std_psf, /undefined) THEN BEGIN ; Read standard map for specified camera ; Read the 200x200 standard star for the appropriate camera ; Extract the scaling factors for the equatorial mapping from the header ; The standard star map std_map has non-zero positive values ; everywhere inside the PSF std_psf = new_psf std_wing = IsType(wing_radius,/defined) std_cam = camera std_map = readfits(filepath(root=who_am_i(/dir),'standard_star_'+std_psf+'.fts.gz'),exten_no=std_cam-1,hdr, /silent) std_origin = [fxpar(hdr,'CX'), fxpar(hdr,'CY')]-1 ; 0-based array index std_scale = 1.0/(fxpar(hdr,'BD')) ; degrees per bin (=0.025) std_in_psf = std_map NE 0 message, /info, 'standard_star_'+std_psf+'.fts.gz (camera'+strcompress(std_cam)+')' IF NOT use_filled_psf AND std_wing THEN BEGIN base = 0;800 radial = 1.259 tangential = 1.585 ndim = size(std_map,/dim) old_map = std_map-base*std_in_psf new_map = old_map right = ndim[0]/2 left = right-1 band = 12 high = ndim[1]/2 low = high-1 FOR i=left-band,right+band DO BEGIN FOR j=low,0,-1 DO $ IF new_map[i,j] EQ 0 THEN $ new_map[i,j] = new_map[i,j+1]/radial FOR j=high,ndim[1]-1,1 DO $ IF new_map[i,j] EQ 0 THEN $ new_map[i,j] = new_map[i,j-1]/radial ENDFOR FOR j=0,ndim[1]-1 DO BEGIN FOR i=left-band-1,0,-1 DO $ IF new_map[i,j] EQ 0 THEN $ new_map[i,j] = new_map[i+1,j]/tangential FOR i=right+band+1,ndim[0]-1,1 DO $ IF new_map[i,j] EQ 0 THEN $ new_map[i,j] = new_map[i-1,j]/tangential ENDFOR ;new_map = smooth(new_map,3) ;new_map[inside_psf] = old_map[inside_psf] std_map = new_map ENDIF ENDIF map = std_map origin = std_origin scale = std_scale/dpm in_psf = std_in_psf not_in_psf = 1B-in_psf nomansland_id = -1.0 background_id = -2.0 wayoutside_id = -3.0 InitVar, get_origin , /key InitVar, get_scale , /key InitVar, get_ndim , /key InitVar, get_fov , /key InitVar, get_nomansland_id, /key InitVar, get_background_id, /key InitVar, get_wayoutside_id, /key IF get_origin THEN RETURN, origin IF get_scale THEN RETURN, scale IF get_ndim THEN RETURN, size(map,/dim) IF get_fov THEN RETURN, size(map,/dim)*scale IF get_nomansland_id THEN RETURN, nomansland_id IF get_background_id THEN RETURN, background_id IF get_wayoutside_id THEN RETURN, wayoutside_id CASE 1 OF IsType(bkgnd_radius, /defined): BEGIN ; Around the PSF create an ellipsoidal area of zeros used ; to pin down the background. Outside the background area ; the map is set to -1.0 p = size(map,/dim) ; Dimensions of standard map p = gridgen(p, origin=(p-1.0)/2.0) ; Hor/vert indices across standard ; map relative to center of map ; The ellipse has semi-major axes of radius/psfstretch[0] in ; the horizontal (RA) dimension and radius/psfstretch[1] in ; the vertical (dec; usually psfstretch[1]=1.0) dimension, ; i.e. the equation for the ellipse is ; (x*psfstretch[0]/radius)^2 + (y*psfstretch[1]/radius)^2 = 1 ; (<1 inside, > 1 outside ellipse). InitVar, psfstretch, [1.0,1.0] p[0,*] *= psfstretch[0] p[1,*] *= psfstretch[1] p *= scale ; Convert to angular units InitVar, bkgnd_origin, [0.0,0.0] ; Shift origin of ellipse p -= bkgnd_origin#(replicate(1,n_elements(p)/2)) CASE n_elements(bkgnd_radius) OF 1: BEGIN p /= bkgnd_radius ; Outer radius only p = total(p*p,1) ; Select bins in standard map that are NOT part of the PSF and are ; outside the ellipse p_near = -1 ; No inner radius p_back = where(p LE 1.0 AND not_in_psf); Inside ellipse p_far = where(p GT 1.0 AND not_in_psf); Outside outer radius END 2: BEGIN q = p/bkgnd_radius[0] ; Inner radius p /= bkgnd_radius[1] ; Outer radius p = total(p*p,1) q = total(q*q,1) ; Select bins in standard map that are NOT part of the PSF and are ; inside the inner ellipse or outside the outer ellipse p_near = where(q LT 1.0 AND not_in_psf) ; Inside inner radius p_back = where(1.0 LE q AND p LE 1.0 AND not_in_psf) ; In ring p_far = where(p GT 1.0 AND not_in_psf) ; Outside outer radius END ENDCASE END IsType(wing_radius,/defined): BEGIN ; Extend the PSF by an ellipoidal area defined by an exponential ; dropoff of the PSF intensity. p = size(map,/dim) ; Dimensions of standard map p = gridgen(p, origin=(p-1.0)/2.0) ; Hor/vert indices across standard ; map relative to center of map ; The ellipse has semi-major axes of radius/psfstretch[0] in ; the horizontal (RA) dimension and radius/psfstretch[1] ; in the vertical (dec; usually psfstretch[1]=1.0) dimension, ; i.e. the equation for the ellipse is ; (x*psfstretch[0]/radius)^2 + (y*psfstretch[1]/radius)^2 = 1 ; (<1 inside, > 1 outside ellipse). InitVar, psfstretch, [1.0,1.0] p[0,*] *= psfstretch[0] p[1,*] *= psfstretch[1] p *= scale ; Convert to angular units InitVar, wing_origin, [0.0,0.0] ; Shift origin of ellipse p -= wing_origin#(replicate(1,n_elements(p)/2)) InitVar, wing_delta , 0.0 p[0,*] /= wing_radius[0]+wing_delta[0] p[1,*] /= wing_radius[n_elements(wing_radius)-1]+wing_delta[n_elements(wing_delta)-1] p = total(p*p,1) ; Select bins in standard map that are NOT part of the PSF ; and are outside the ellipse. Set the standard map to ; zero outside the ellipse. q = where(p GT 1.0 AND not_in_psf) IF q[0] NE -1 THEN map[q] = 0.0 p_near = -1 ; No inner radius p_back = -1 ; No outer radius p_far = where(map LE 0.0) ; Outside outer radius END ELSE: BEGIN ; Use the unmodified PSF p_near = -1 ; No inner radius p_back = -1 ; No outer radius p_far = where(map LE 0.0) ; Outside PSF END ENDCASE IF p_near[0] NE -1 THEN map[p_near] = nomansland_id IF p_back[0] NE -1 THEN map[p_back] = background_id IF p_far [0] NE -1 THEN map[p_far ] = wayoutside_id ; 0: outside area ; 1: wing area ; 2: original PSF (in_psf) IF show THEN $ view, in=map+(1-map)*(map GT 0)+in_psf, /stretch RETURN, map & END