;+
; NAME:
;	FINDTTREF
;
; PURPOSE:
;	Search the USNO-B1.0 catalogue for tip-tilt reference stars for each
;	object in a Keck starlist.  Output is a target list in Keck LGS-AO
;	format, either to standard output or to a user-specified filename.
;
; EXPLANATION:
;	Uses the IDL Astronomy User's Library routine QUERYVIZIER to query the
;	USNO-B1.0 catalogue for stars around each object in the target list.
;	A model of the Strehl vs. magnitude and off-axis angle are then used
;	to identify the optimum reference star.
;
; CALLING SEQUENCE:
;	FINDTTREF, starlist, output_filename [, RMAG=, SEP=, NMAX=, ISOKIN=]
;
; INPUTS:
;	starlist - the full path to a Keck-format starlist.  If not given,
;		will prompt user to choose one using DIALOG_PICKFILE.
;
; OPTIONAL INPUTS:
;	output_filename - a filename to which to output the LGSAO starlist.
;		If not defined, output will be to command line.
;
; OPTIONAL INPUT KEYWORDS:
;	RMAG - a 2-element vector giving a the range of R magnitudes allowed
;		for tip-tilt reference stars.  Default = [8.0, 19.0].
;
;	SEP - a 2-element vector giving the range of separation in arcseconds
;		allowed for tip-tilt reference stars.  Default = [0, 90].
;
;	NMAX - the maximum number of tip-tilt references to list for each
;		object.  Default = 3.
;
;	ISO - An estimate of the LGSAO isokinetic angle, in arcseconds.
;	  Default = 40.0
;
;	EFFWAVE - Effective central wavelength of the science observations,
;		in microns, used for estimating Strehl.  Default = 2.124
;
;	/NOSTREHL - suppress the ouput of the estimated Strehl on target
;		for each tip-tilt reference star (very crude estimate).
;
;	/CHECK2MASS - Retrieve 2MASS Point Source Catalog data for 
;                     each USN0 star and inform user if 
;                            it matches an extended object
;                        or  it matches a Kmag Point Source
; PROCEDURES USED:
;	Functions:	QUERYVIZIER(), READSTARLIST(), STARSTRING()
;	Procedures:	GCIRC, COPY_STRUCT
;
; NOTES:
;	QUERYVIZIER uses the SOCKET procedure, which requires IDL 5.4 or later.
;
; MODIFICATION HISTORY:
;	Original version written 02/04, A. Bouchez, WM Keck Observatory.
;	Updated output format, added Strehl optimization; 10/04, A. Bouchez
;       Added estimation and output for b-v, b-r; June 2005 DLM 
;       Added /check2mass option and set SEP default to 90.0 arcsec. March 2006 DLM
;-
PRO	FINDTTREF, starlist, output_filename, rmag=rmag, sep=sep, nmax=nmax, $
                   iso=iso, effwave=effwave, nostrehl=nostrehl, check2mass=check2mass

;;; 1. Set defaults

  npar = N_PARAMS()
  if npar eq 0 then begin
     default_path = '/net/ulua/local/kroot/starlists/'
     starlist = DIALOG_PICKFILE(path=default_path, tit='Select a starlist')
  endif
  if not KEYWORD_SET(output_filename) then $
     output_filename='std_out'
  if not KEYWORD_SET(rmag) then rmag = [8.0, 19.0]
  if not KEYWORD_SET(sep) then sep = [0, 90.]
  if not KEYWORD_SET(nmax) then nmax = 3
  if not KEYWORD_SET(iso) then iso = 40.0
  if not KEYWORD_SET(effwave) then effwave = 2.124

  kstrehl = [[10, 0.35], [11, 0.35], [12, 0.35], $ ; K Strehl vs. R mag.
             [13, 0.34], [14, 0.32], [15, 0.30], $ ;  (07/04-09/04 Eng.)
             [16, 0.27], [17, 0.23], [18, 0.18], $
             [19, 0.12]]
  rms = kstrehl
  rms[1,*] = 2124/(2*!pi)*SQRT(-1*ALOG(kstrehl[1,*])) ; RMS WF error (nm)
  
;;; 2. Read starlist, open output file

  tlist = READSTARLIST(starlist)
  nt = N_ELEMENTS(tlist)
  lgslist = REPLICATE(tlist[0],nt*(1.+nmax))
  tmp = tlist[0]
  if output_filename ne 'std_out' then begin
     PRINT,'Output starlist: ' + output_filename
     OPENW, unit, output_filename, /get_lun
     FREE_LUN, unit
  endif

;;; 3. List target, adding 'lgs=1' if not present, download USNO-B1 data.

  nr = 0
  for l=0,nt-1 do begin
     lgslist[nr] = tlist[l]
     if STRPOS(lgslist[nr].comment,'lgs=1') eq -1 then $
        lgslist[nr].comment = lgslist[nr].comment + ' lgs=1'
     str = STARSTRING(lgslist[nr])
     if output_filename ne 'std_out' then begin
        PRINT,'Targ: ' + str
        OPENU, unit, output_filename, /append, /get_lun
        PRINTF, unit, str
        FREE_LUN, unit
     endif else $
        PRINT, str

     nr  = nr + 1
     radec = [ tlist[l].raj2000, tlist[l].dej2000 ]
     dradec = MAX(sep) * [2/60., 2/60.] ; Field width (arcmin)
     usno = QUERYVIZIER('USNO-B1',radec,dradec) ; Download USNO stars

;;; 4. Find stars in with Rmag and separation in desired range

     if (SIZE(usno))[0] ne 0 then begin
        usno_rmag = (usno.r1mag + usno.r2mag)/2. ; R magnitude (R1 or R2)
        usno_bmag = (usno.b1mag + usno.b2mag)/2. ; R magnitude (B1 or B2)
        w1 = WHERE(FINITE(usno.r2mag) ne 1)
        if w1[0] ne -1 then usno_rmag[w1] = usno[w1].r1mag
        w2 = WHERE(FINITE(usno.r1mag) ne 1)
        if w2[0] ne -1 then usno_rmag[w2] = usno[w2].r2mag

        w3 = WHERE(FINITE(usno.b2mag) ne 1)
        if w3[0] ne -1 then usno_bmag[w3] = usno[w3].b1mag
        w4 = WHERE(FINITE(usno.b1mag) ne 1)
        if w4[0] ne -1 then usno_bmag[w4] = usno[w4].b2mag

        GCIRC,1,tlist[l].raj2000/15,tlist[l].dej2000,$ ; Separation (arcsec)
              usno.raj2000/15,usno.dej2000,usno_sep

        w = WHERE(usno_sep ge MIN(sep) and $ ; acceptable guidestars
                  usno_sep lt MAX(sep) and $
                  usno_rmag ge MIN(rmag) and $
                  usno_rmag lt MAX(rmag), ns)	

        ;; estimate B-R and B-V for the stars
        usno_brmag = usno_bmag - usno_rmag ; B-R color magnitude 
        if w2[0] ne -1 then usno[w2].r1mag = usno[w2].r2mag
        if w4[0] ne -1 then usno[w4].b1mag = usno[w4].b2mag	
        usno_bvmag = 0.556*(usno.b1mag - usno.r1mag) ; B-V color magnitude 
        ;; approximation from http://www.aerith.net/astro/color_conversion.html


;;; 5. Sort TTrefs by predicted Strehl

        if w[0] ne -1 then begin
           rms_mag = INTERPOL(rms[1,*], rms[0,*], usno_rmag[w])
           rms_iso = ((effwave*1e3*usno_sep[w])/(2*!pi*iso))^(5/6.) ; Hardy Eq7.61
           rms_tot = SQRT(rms_mag^2 + rms_iso^2)
           strehl = EXP(-1*(2*!pi*rms_tot/(effwave*1e3))^2) ; Est. Strehl
           srt = SORT(1-strehl)
           for n=0,(nmax<ns)-1 do begin
              i = w[srt[n]]
              tmp.targ = STRING(usno[i].usno_b1_0,f='(A15)')
              tmp.rah = FIX(usno[i].raj2000 / 15.)
              tmp.ram = FIX( (usno[i].raj2000 - tmp.rah*15.) * 60/15. )
              tmp.ras = (usno[i].raj2000 - (tmp.rah*15.) - $
                         (tmp.ram*15./60) ) * 3600/15.
              if usno[i].dej2000 ge 0 then $
                 tmp.design = '+' else tmp.design = '-'
              tmp.ded = ABS( FIX(usno[i].dej2000) )
              tmp.dem = ABS( FIX( (ABS(usno[i].dej2000) - tmp.ded) * 60. ) )
              tmp.des = ABS( (ABS(usno[i].dej2000) - tmp.ded - $
                              tmp.dem/60.) * 3600. )
              tmp.equ = 2000.0
              if FINITE(usno_brmag[i]) ne 0 then $ 
                 tmp.comment = 'rmag=' + $
                               STRTRIM(STRING(usno_rmag[i],f='(F4.1)'),2) + ' sep=' + $
                               STRTRIM(STRING(usno_sep[i],f='(F5.1)'),2) + ' b-v=' + $
                               STRTRIM(STRING(usno_bvmag[i],f='(F5.2)'),2) + ' b-r=' + $
                               STRTRIM(STRING(usno_brmag[i],f='(F5.2)'),2) + ' S=' + $
                               STRTRIM(STRING(strehl[srt[n]],f='(F4.2)'),2)  else $
                                  tmp.comment = 'rmag=' + $
                                                STRTRIM(STRING(usno_rmag[i],f='(F4.1)'),2) + ' sep=' + $
                                                STRTRIM(STRING(usno_sep[i],f='(F5.1)'),2) +  ' S=' + $
                                                STRTRIM(STRING(strehl[srt[n]],f='(F4.2)'),2)  

              tmp.raj2000 = usno[i].raj2000
              tmp.dej2000 = usno[i].dej2000

              if KEYWORD_SET(check2mass) then begin
                 radec = [tmp.raj2000, tmp.dej2000 ]
                 twomass = QUERYVIZIER('2MASS-PSC', double(radec), 3.0)
                 if (SIZE(twomass))[0] ne 0 then begin
                    GCIRC,1,tmp.raj2000/15,tmp.dej2000,$ ; Separation (arcsec)
                          twomass.raj2000/15,twomass.dej2000,twomass_sep
                    d2_10 = WHERE(twomass_sep gt 2.0 and twomass_sep lt 10.0)	
                    d2 = WHERE(twomass_sep le 2.0)	
                    if d2[0] ne -1 then begin
                       ext = WHERE(twomass[d2].xflg eq 1)                    
                       gal = WHERE(twomass[d2].xflg eq 2)
                       if ext[0] ne -1 then $
                          tmp.comment = tmp.comment+' 2MASS=ExtObj'
                       if gal[0] ne -1 then $
                          tmp.comment = tmp.comment+' 2MASS=Gal'
                       tmp.comment = tmp.comment+$
                                     ' kmag='+STRTRIM(STRING(twomass[d2[0]].kmag,f='(F5.1)'),2) 
                    endif
                    if (d2_10[0] ne -1) and (d2[0] eq -1)  then begin
                          ext = WHERE(twomass[d2_10].xflg eq 1)
                          gal = WHERE(twomass[d2_10].xflg eq 2)
                          if ext[0] ne -1 then $
                             tmp.comment = tmp.comment+' 2MASS=NearExtObj'
                          if gal[0] ne -1 then $
                             tmp.comment = tmp.comment+' 2MASS=InGal'
                          tmp.comment = tmp.comment+$
                                        ' kmag='+STRTRIM(STRING(twomass[d2_10[0]].kmag,f='(F5.1)'),2) 
                       endif
                 endif
              endif
                 
;;; 6. Output to file or command line and continue

              str = STARSTRING(tmp)
              if output_filename ne 'std_out' then begin
                 OPENU, unit, output_filename, /append, /get_lun
                 PRINTF, unit, str
                 FREE_LUN, unit
              endif else $
                 PRINT, str

              lgslist[nr] = tmp ; insert in list
              nr = nr + 1       ; increment nr
           endfor
        endif
     endif
  endfor
  lgslist = lgslist[0:nr-1]
  
END