;
; modifications to studio.pro
; save structure containing image, lat, lon, mlat, mlon, sza,
; dza, (spacecrqaft zenith angle), time, l0, ra, dec, alt, o_gci,
; save right ascension and declination for each pixel and
; display position of the Moon, Saturn, and RA-DEC grid: 9/10/2003 MOF
; added EPS option: 7/28/2003 MOF
; LOS correction done for LBHS: 7/28/2003 MOF (see 3/23/05 mod. below)
;
; modified get_dsp_angles -- it should now work better with the updated
; platform_slews.list for the latter part of the mission when the
; dsp angle is undersampled: 6/16/2004 MOF
;
; modified latitude limit under 'Plot Options'
; now choose from 60, 50, 40, 30, 20, 10, or 0 degrees latitude
; 1/19/2005 MOF
;
; modified LOS correction:
; don't automatically do LOS correction if removing dayglow
; (but still will in practice)
; for LBHS filter, don't do correction, but remove large angle pixels
;
; for all filters except LBHL, LOS correction removes large angle pixels,
; but does not actually do correction
; 3/23/05 MOF
;
; studio modified in June 2006 to remove option to overlay FAST orbit
; and to get it ready for final release - version 6.4 (MAS)
;
;--------------------------------------------------------------
; AUXILLIARY FUNCTIONS
;--------------------------------------------------------------

FUNCTION chk_leap_year,year

return_val = 0
;divisible by 4 and not centurial year
IF((year MOD 4) EQ 0)  AND  ((year MOD 100) NE 0) THEN  $
  return_val = 1
;divisible by 400
IF(year MOD 400) EQ 0 THEN return_val = 1
RETURN,return_val

END

;--------------------------------------------------------------

FUNCTION get_doy,day,month,year

days_per_month = [31,28,31,30,31,30,31,31,30,31,30,31]
doy = 0
FOR i = 0,month-2 DO BEGIN
  doy = doy + days_per_month(i)
ENDFOR
doy = doy + day
is_leap_year = chk_leap_year(year)
IF(is_leap_year) AND (month GT 2) THEN doy = doy + 1

RETURN,doy

END

;--------------------------------------------------------------

PRO get_month_day_year, doy, day, month, year

days_per_month = [31,28,31,30,31,30,31,31,30,31,30,31]
 
IF doy EQ 0 THEN BEGIN
  year = year - 1
  month = 12
  day = 31
  return
ENDIF
 
month = 0
tmp_doy = doy
 
; If it's a leap year fix the number of days in the month.
IF chk_leap_year( year ) THEN days_per_month( 1 ) = 29
 
WHILE( (tmp_doy GT days_per_month( month )) AND (month LE 10) ) DO BEGIN
  tmp_doy = tmp_doy - days_per_month( month )
  month = month + 1
ENDWHILE
 
; Correct the month so it runs from 1-12 instead of 0-11
month = month + 1
day = tmp_doy
 
END

;--------------------------------------------------------------

FUNCTION check_for_backslash,path

IF (path NE '') THEN BEGIN
  char = STRMID(path,STRLEN(path)-1,1)
  IF (char NE '/') THEN path = path + '/'
ENDIF

RETURN, path

END

;--------------------------------------------------------------

FUNCTION get_file_id,file

str_len = STRLEN(file)
extension = '' 
id = 0L
IF (str_len GT 3) THEN extension = STRMID(file,str_len-3,3) $
  ELSE id = -1
IF (extension EQ 'cdf') OR (extension EQ 'CDF') THEN $
  id = CDF_OPEN(file) ELSE id = -1

RETURN, id
END

;--------------------------------------------------------------

FUNCTION fileChooser,path=path,filter=filter,title=title

file=PICKFILE(PATH=path,FILTER=filter,GET_PATH=path,TITLE=title)

IF (file EQ '') THEN BEGIN
  display_message,'File not available.....',/erase_screen
  display_message,'Try again!'
ENDIF 

RETURN, file

END

;--------------------------------------------------------------

FUNCTION get_mlt, year, doy, utsec, alon, sslon

; determine the MLT associated with a given apex longitude, using
; Art Richmond's algorithm, which defines MLT as the difference in
; longitude between the dipol magnetic longitude of the subsolar
; point, and the apex longitude of the point of interest.
;
; input is year, day of year (1 Jan = 1), time (UT in seconds since
;          0:00:00), and apex longitude (array or individual number)
; returns MLT of the given apex longitude

; first get the subsolar point in geographic coordinates

subsol, year, doy, utsec=utsec, sslat, sslon

; then get the dipole coordinates of this point

geo_2_mag, sslat, sslon, ssmlat, ssmlon, pole=[10.66, -71.50] 

; now do the conversion to MLT (nn must be an integer)

nn = 2
mlt = (alon-ssmlon)/15. + 12.
mlt = ((mlt+24*nn) mod 24)

RETURN, mlt

END

;--------------------------------------------------------------

FUNCTION make_filetag,record

COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON STRUCTURES

rx = WHERE(recnum EQ record)
IF !VERSION.OS EQ 'Win32' THEN BEGIN
  file_tag = lb(rx).hour_str + lb(rx).minute_str + lb(rx).second_str $
           + '_g'
ENDIF ELSE BEGIN
  file_tag = lb(rx).year_str + lb(rx).month_str + lb(rx).day_str + '_' $
           + lb(rx).hour_str + lb(rx).minute_str + lb(rx).second_str
ENDELSE

RETURN, file_tag

END

;--------------------------------------------------------------

FUNCTION shuffle, num, PRAND=prand, COUNT=count

primes = [ 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 47, 53, $
	59, 61, 67, 71, 79, 83, 89, 97, 101 ]

possible = WHERE( primes LE num, count )

IF count EQ 0 THEN RETURN, [ 0 ]

IF count LE 2 THEN RETURN, FINDGEN( count )

prime = primes( possible( count - 1) )
mult = primes( possible( count - 2 ) )

result = FIX(FINDGEN( num ))

tmp = 0
tmp2 = FIX(FINDGEN( prime ))

IF NOT KEYWORD_SET( prand ) THEN prand = 3

WHILE tmp LT num DO BEGIN
  FOR i = 0, prand DO $
    tmp2 = ((tmp2 + 1) * mult) MOD prime

  result = result( tmp2 )

  result = SHIFT( result, prime / 2 + 1 )

  tmp = tmp + prime / 2 + 1
ENDWHILE

RETURN, result

END

;--------------------------------------------------------------

FUNCTION vec_dot,u,v

RETURN, DOUBLE(u(0)*v(0) + u(1)*v(1) + u(2)*v(2))

END

;--------------------------------------------------------------

FUNCTION vec_norm,v

RETURN, SQRT(vec_dot(v,v))

END

;--------------------------------------------------------------

FUNCTION unit_vec,v

RETURN, v/vec_norm(v)

END

;--------------------------------------------------------------

FUNCTION xy_orient,v,system

u = FLTARR(2)

CASE system OF
  1: BEGIN
       u(0) = 199 - v(0)
       u(1) = 227 - v(1)
     END
  2: BEGIN
       u(0) = 199 - v(0)
       u(1) = v(1)
     END
ENDCASE

RETURN, u

END

;--------------------------------------------------------------

FUNCTION interp2p,x1,x2,x,f1,f2

RETURN, f1 + (f2-f1)*(x-x1)/(x2-x1)

END

;--------------------------------------------------------------
; AUXILLIARY PROCEDURES
;--------------------------------------------------------------

PRO area_los,rsat,sslat,sslon,lat,lon,system,area,los,inv_los, $
  NOT_LBHL = not_lbhl

dtor = !DPI/180.D
Re = 6371.D
norm_rsat = rsat/Re

CASE system OF
  1: solid_ang = 0.03380D*dtor*0.03987D*dtor ; from Swift
  2: solid_ang = 0.03511D*dtor*0.04178D*dtor ; 10/1/97
ENDCASE
nadir = (rsat - Re)*(rsat - Re)*solid_ang

the = REPLICATE(0.,200,228)
phi = REPLICATE(0.,200,228)

;comp_area = 90. * dtor
area = REPLICATE(0.,200,228)

;comp_los = 1.5097585 ; =86.5 degrees, max of function
los = REPLICATE(1.,200,228)
inv_los = REPLICATE(0.,200,228)

indx = WHERE(lat GT -90., count)

IF (count GT 0) THEN BEGIN

  lat1 = sslat*dtor
  lat2 = lat*dtor
  lon1 = sslon*dtor
  lon2 = lon*dtor

  the = DOUBLE(ACOS(SIN(lat1)*SIN(lat2) + $
            COS(lat1)*COS(lat2)*COS(lon1-lon2)))
  phi = DOUBLE( ATAN( SIN(the) , norm_rsat - COS(the) ) )

  ang = the + phi

  area(indx) = DOUBLE(nadir/COS(ang(indx)))

;  simple formula
;  indx_los = WHERE(ang LT comp_los)
;  los(indx) = DOUBLE( 1./COS(ang(indx)) )

; Glynn's empirical fit
;  los(indx) = DOUBLE(1.D/COS(ang(indx)))
  los(indx) = DOUBLE(EXP(0.061*(1. - $
               1./COS(ang(indx))))/COS(ang(indx)))

  ; find inverse of LOS
  maxang = 78.*dtor
  maxlos = 5.  ;(maximum angle from nadir is 78 deg)
  gndx = WHERE( (lat GT -90.) AND (ang LT maxang), ngndx )
  IF (ngndx GT 0) THEN inv_los[gndx] = 1./los[gndx]

; If not LBHL, don't do LOS correction, but remove large angle pixels
  IF (KEYWORD_SET(NOT_LBHL)) THEN $
    IF (ngndx GT 0) THEN inv_los[gndx] = 1.
ENDIF

END

;--------------------------------------------------------------

; PROCEDURE get_oa_files,yyyymmdd,orb_file,att_file
;
; Search for the latest versions of the orbit and attitude files
;
; Parameters
;    img_file  (input)   image file
;    orb_file  (output)  orbit file
;    att_file  (output)  attitude file

PRO get_oa_files,yyyymmdd,orb_file,att_file

COMMON STRUCTURES

;Find all versions of the predict orbit files for the desired time
strTmp = path.orb + 'po_or_pre_' + yyyymmdd + '*.cdf' 
preOrbFiles = FINDFILE(strTmp, COUNT=count)
IF count GT 0 THEN BEGIN
  ;Sort the predict files so that the latest version is first
  preOrbFiles = preOrbFiles(REVERSE(SORT(preOrbFiles)))
  ;Use the latest version
  orb_file = preOrbFiles(0)
ENDIF ELSE BEGIN
  ;There are no predict orbit files for this day.
  ;Look for definitive orbit files.
  strTmp = path.orb + 'po_or_def_' + yyyymmdd + '*.cdf' 
  defOrbFiles = FINDFILE(strTmp, COUNT=count)
  IF count EQ 0 THEN BEGIN
    ; search failed! Let the user look for it
    orb_file=PICKFILE(PATH=path.orb,FILTER='*.cdf',GET_PATH=path.orb,$
    TITLE='Please Select Orbit File')
  ENDIF ELSE BEGIN
    ;Sort the definitive orbit files in descending order so that
    ;the latest file is first
    defOrbFiles = defOrbFiles(REVERSE(SORT(defOrbFiles)))
    ;Use the latest file
    orb_file = defOrbFiles(0)
  ENDELSE
ENDELSE

;Find all versions of the predict attitude files for the desired time
strTmp = path.att + 'po_at_pre_' + yyyymmdd + '*.cdf' 
preAttFiles = FINDFILE(strTmp, COUNT=count)
IF count GT 0 THEN BEGIN
  ;Sort the predict files so that the latest version is first
  preAttFiles = preAttFiles(REVERSE(SORT(preAttFiles)))
  ;Use the latest version
  att_file = preAttFiles(0)
ENDIF ELSE BEGIN
  ;There are no predict attitude files for this day.
  ;Look for definitive attitude files.
  strTmp = path.att + 'po_at_def_' + yyyymmdd + '*.cdf' 
  defAttFiles = FINDFILE(strTmp, COUNT=count)
  IF count EQ 0 THEN BEGIN
    ; search failed! Let the user look for it
    att_file=PICKFILE(PATH=path.att,FILTER='*.cdf',GET_PATH=path.att,$
      TITLE='Please Select Attitude File')
  ENDIF ELSE BEGIN
    ;Sort the definitive attitude files in descending order so that
    ;the latest file is first
    defAttFiles = defAttFiles(REVERSE(SORT(defAttFiles)))
    ;Use the latest file
    att_file = defAttFiles(0)
  ENDELSE
ENDELSE

END

;---------------------------------------------------------------------------
; PROCEDURE get_dsp_files,dsp_file,dsp_file_prev,msl=msl
;
; Search for the latest versions of the platform angle files
;
; Parameters
;    img_file  (input)   image file
;    dsp_file  (output)  despun platform angle file
;    dsp_file_prev  (output)  despun platform angle file for previous day

PRO get_dsp_files,img_file,dsp_file,dsp_file_prev,pre=pre,psl=psl

COMMON STRUCTURES

spos = STRPOS(img_file,'uvi_')
yyyymmdd = STRMID(img_file,spos+4,8)

;Find all versions of the definitive pitch angle files for the desired days.
strTmp = path.dsp + 'po_pa_def_' + yyyymmdd + '*.cdf'
defPaFiles = FINDFILE(strTmp, COUNT=count)
IF count EQ 0 THEN BEGIN
  ; search failed! Read the platform_slews.list file
  psl = 1
  ; search failed! Let the user look for it
  ; dsp_file=PICKFILE(PATH=path.dsp,FILTER='*.cdf',GET_PATH=path.dsp,$
  ;   TITLE='Please Select Pitch Angle File')
ENDIF ELSE BEGIN
  ;Sort the predict files so that the latest version is first
  defPaFiles = defPaFiles(REVERSE(SORT(defPaFiles)))
  ;Use the latest version
  dsp_file = defPaFiles(0)
ENDELSE
 
IF pre THEN BEGIN 
  ;Find the previous days definitive pitch angle files for the desired days.
  year = FIX( STRMID( yyyymmdd, 0, 4 ) )
  month = FIX( STRMID( yyyymmdd, 4, 2 ) )
  day = FIX( STRMID( yyyymmdd, 6, 2 ) )
  prev_doy = get_doy( day, month, year ) - 1
  get_month_day_year, prev_doy, day, month, year
  yyyymmdd = STRING( year, month, day, FORMAT="(i4.4, i2.2, i2.2)" )
  strTmp = path.dsp + 'po_pa_def_' + yyyymmdd + '*.cdf'
  preAttFiles = FINDFILE(strTmp, COUNT=count)
  IF count EQ 0 THEN BEGIN
    ; search failed! Let the user look for it
    dsp_file_prev=PICKFILE(PATH=path.dsp,FILTER='*.cdf',GET_PATH=path.dsp,$
      TITLE='Please Select the Previous Days Pitch Angle File')
  ENDIF ELSE BEGIN
    ;Sort the predict files so that the latest version is first
    preAttFiles = preAttFiles(REVERSE(SORT(preAttFiles)))
    ;Use the latest version
    dsp_file_prev = preAttFiles(0)
  ENDELSE
ENDIF

END

;--------------------------------------------------------------

PRO  extract_image,img_id,record,image

COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON STRUCTURES

image = INTARR(200,228)
sub_image = INTARR(50,228)

IF !VERSION.OS EQ 'Win32' THEN BEGIN
  ;The CDF interface under the 32-bit Windows versions of IDL
  ;cannot handle transfers of >64K.  We have to read the
  ;image in 4 passes.
  CDF_VARGET,img_id,'INT_IMAGE',sub_image,REC_START=record, $
      OFFSET=[0,0],COUNT=[50,228]
  image(0:49,*) = sub_image
  CDF_VARGET,img_id,'INT_IMAGE',sub_image,REC_START=record, $
      OFFSET=[50,0],COUNT=[50,228]
  image(50:99,*) = sub_image
  CDF_VARGET,img_id,'INT_IMAGE',sub_image,REC_START=record, $
      OFFSET=[100,0],COUNT=[50,228]
  image(100:149,*) = sub_image
  CDF_VARGET,img_id,'INT_IMAGE',sub_image,REC_START=record, $
      OFFSET=[150,0],COUNT=[50,228]
  image(150:199,*) = sub_image
ENDIF ELSE BEGIN
  CDF_VARGET,img_id,'INT_IMAGE',image,REC_START=record
ENDELSE

;;;;;;;HACK
dosum = 0
;read,'enter number of images to average or 0:',dosum
if dosum then begin
tot_img = dosum
print,'HACK: averaging ',tot_img,' images....'
num_img = 0
sum = fltarr(200,228)
step = -1
rec = record > 50
sav_rec = record

WHILE (num_img LT tot_img) DO BEGIN
  filter = ii(rec).filt
  rate = ii(rec).rate
  IF ( (filter EQ 4) AND ( rate EQ 4 ) ) THEN BEGIN
    CDF_VARGET,img_id,'INT_IMAGE',image,REC_START=rec
    sum = sum + image 
    num_img = num_img + 1
    IF ( num_img EQ CEIL(0.5*tot_img) ) THEN BEGIN
      rec = sav_rec + 1
      step = 1
    ENDIF
  ENDIF
  rec = rec + step
ENDWHILE

image = sum/tot_img
endif
;;;;;;;ENDHACK

END

;--------------------------------------------------------------

PRO make_background,apogee_record

COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz
COMMON IDS, img_id,orb_id,att_id,dsp_id,dsp_prev_id
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON IMAGES,raw_img
COMMON AUXIL
COMMON STRUCTURES

record = apogee_record
num_bak = 0
tot_bak = 25
bak_arr = FLTARR(tot_bak,nxpix,nypix)
bkg_img = FLTARR(nxpix,nypix)
step = 1

WHILE (num_bak LT tot_bak) DO BEGIN
  filter = ii(record).filt
  table_number = ii(record).tbln
  IF ( (filter EQ 0 OR filter EQ 6) AND table_number EQ 0 ) THEN BEGIN
      extract_image,img_id,record,image
      bak_arr(num_bak,*,*) = image
      num_bak = num_bak + 1
  ENDIF
  record = record + step
  IF (record GE endRec) THEN BEGIN
    record = apogee_record - 1
    step = -1
  ENDIF
  IF (record EQ -1) THEN BEGIN
    bkg_img = 28.0
    display_message,'....no background available'
    display_message,'WARNING! background set to 28'
    WAIT,1.0
    RETURN
  ENDIF
ENDWHILE

; use median value for background
FOR i=0,nxpix-1 DO BEGIN
  FOR j=0,nypix-1 DO BEGIN
    bkg_img(i,j) = MEDIAN(bak_arr(*,i,j))
  ENDFOR
ENDFOR

; test background
mean_back = MEAN( bkg_img(WHERE(bkg_img GT 1)) )
mean_str = STRING( mean_back ,FORMAT='(I4)')
display_message,'....mean of background is '+mean_str
IF (mean_back GT 30.) THEN BEGIN
  IF (mean_back GT 32) THEN BEGIN
    bkg_img[*] = 28.
    display_message,'WARNING! background > 32'
    display_message,'WARNING! background set to 28'
  ENDIF ELSE $
    display_message,'WARNING! 30 < background < 32'
  WAIT,2.0
ENDIF

END

;--------------------------------------------------------------

FUNCTION dewob_image,image

COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz

margin = 5

; create copies of the image shifted up and down by offset
offset = margin
upr_img = FLTARR(nxpix,nypix+2*margin)
lwr_img = FLTARR(nxpix,nypix+2*margin)
fin_img = FLTARR(nxpix,nypix+2*margin)
bot_val = margin + offset
upr_img(*,bot_val:bot_val+nypix-1) = image
bot_val = margin - offset
lwr_img(*,bot_val:bot_val+nypix-1) = image

; choose the lesser of the two
fin_img = lwr_img < upr_img

; extract the new image
bot_val = margin

RETURN, fin_img(*,bot_val:bot_val+nypix-1)

END

;--------------------------------------------------------------

FUNCTION clean_image,image,method

COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz
COMMON IMAGES,raw_img
COMMON AUXIL

CASE method OF

  1: BEGIN
       new_img = image
       old_img = (image - 30.0) > 0.
       npts = 3  ; 9x9 box
       FOR i=npts,nxpix-npts-1 DO BEGIN
         FOR j=npts,nypix-npts-1 DO BEGIN
          med = MEDIAN(old_img(i-npts:i+npts,j-npts:j+npts))
          lim = MAX([ABS(med+7.*SQRT(med)),30.])
          IF (old_img(i,j) GT lim) THEN BEGIN
            new_img(i,j) = med + 30.0
          ENDIF
        ENDFOR
       ENDFOR
       image = new_img
     END

  2: BEGIN 
;       smoothing_scale = 2.
;       threshold = 4.
;       read,'scale,thold = ',smoothing_scale,threshold
;       diff = image - smooth_image(image,smoothing_scale)
       threshold = 3.
       diff = image - dewob_image(image)
       valid = WHERE(bkg_img GT 1.)
       stdv = SQRT( (MOMENT(diff(valid)))[1] )
       ; Find outliers and set image to 0. at these points
       badd = WHERE(diff/stdv GT threshold, BadCount)
       IF (BadCount GT 0) THEN image(badd) = 0.
     END
  ELSE: PRINT,'clean method not available'  
ENDCASE

RETURN, image

END

;--------------------------------------------------------------

PRO display_message,msg,erase_screen=erase_screen,wait=wait

COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes
COMMON WINDINFO,main_windex,xmsg,ymsg,imsg,orbit_windex,model_windex

WSET, main_windex
IF KEYWORD_SET(erase_screen) THEN BEGIN
  ERASE
  imsg = 0
ENDIF
XYOUTS,xmsg(imsg),ymsg(imsg),msg,COLOR=ct(cur_ct).message,$
	/DEVICE,CHARSIZE=1.5
imsg = imsg + 1
IF KEYWORD_SET(wait) THEN WAIT, wait

END

;--------------------------------------------------------------

PRO conv_ct, ct_idx, colors, BOT_CLR=bot_clr, BSTEPS=bsteps

COMMON COLORS, r_orig, g_orig, b_orig, r_curr, g_curr, b_curr
COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes

LOADCT, colors

pos = 0

r_curr = r_orig
g_curr = g_orig
b_curr = b_orig

IF (NOT KEYWORD_SET( bsteps )) OR $
	(NOT KEYWORD_SET( bot_clr)) THEN bsteps = 0

n = ((SIZE(r_orig))(1) - 1.0) / (top_color - bsteps)

IF bsteps GT 0 THEN BEGIN
   FOR i = 0, bsteps - 1 DO BEGIN
     ct(ct_idx).rct(i) = bot_clr(0)+(r_orig( 0 )-bot_clr( 0 ))*i/(1.*bsteps)
     ct(ct_idx).gct(i) = bot_clr(1)+(g_orig( 0 )-bot_clr( 1 ))*i/(1.*bsteps)
     ct(ct_idx).bct(i) = bot_clr(2)+(b_orig( 0 )-bot_clr( 2 ))*i/(1.*bsteps)
   ENDFOR
ENDIF

FOR i=bsteps, top_color DO BEGIN
  ct(ct_idx).rct( i ) = r_orig( FIX( pos ) )
  ct(ct_idx).gct( i ) = g_orig( FIX( pos ) )
  ct(ct_idx).bct( i ) = b_orig( FIX( pos ) )
  pos = pos + n
END

END

;--------------------------------------------------------------

PRO color_value_rgb

COMMON STRUCTURES
COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes

;*******************************************************
; This procedure generates a colortable, including 24 colors
;
;      Written by B. Johannesen  96
;      Modified :
;         97/04/?? N.Ostgaard
;         97/06/?? E Thorsen
;         98/01/?? M Brittnacher
;
;*******************************************************

rct = MAKE_ARRAY(29,/int)
gct = MAKE_ARRAY(29,/int)
bct = MAKE_ARRAY(29,/int)

;*********************************************************
; The red, blue and green vectors
;******************************

;rct = [255,235,210,150, 45, 45, 70, 95,140,190, $
;       230,245,255,255,255,255,255,255,220,180, $
;       140,100, 60,  0, $
;       255, 70,255,  0,  0]

;gct = [255,245,230,240,225,225,235,245,255,255, $
;       250,255,255,238,208,174,127,  0,  0,  0, $
;         0,  0,  0,  0, $
;       255,133,  0,  0,  0]

;bct = [255,240,230,245,210,100, 55, 10,  0,  0, $
;         0,  0,130,  0,  0,  0,  0,  0, 45, 45, $
;        45, 45, 45, 45, $
;       255, 30,  0,  0,255]

;rct = [255,250,245,240,230,220,210, $
rct = [255,230,220,210, $
       150, 45, 45, 70, 95,140,190, $
       230,245,255,255,255,255,255,255,220,180, $
       140,100, 60,  0, $
       255, 70,255,  0,  0]

;gct = [255,254,251,248,242,236,230, $
gct = [255,242,236,230, $
       240,225,225,235,245,255,255, $
       250,255,255,238,208,174,127,  0,  0,  0, $
         0,  0,  0,  0, $
       255,133,  0,  0,  0]

;bct = [255,254,251,248,236,230, $
bct = [255,248,236,230, $
        245,210,100, 55, 10,  0,  0, $
         0,  0,130,  0,  0,  0,  0,  0, 45, 45, $
        45, 45, 45, 45, $
       255, 30,  0,  0,255]

white,r,g,b
rct = r
gct = g
bct = b

dim = (SIZE(rct))(1)
blue = dim - 1
black = dim - 2
red   = dim - 3
green = dim - 4
white  = dim - 5
top_color = dim - 6

n_schemes = 6

ct = REPLICATE( {color_list, MESSAGE: blue, RCT: rct, GCT: gct, $
	BCT: bct, CBAR_PLOT: black, CBAR_AXIS: black, $
	CBAR_LABEL: black, BKGRND_CLR: 0, MLT_LINE: black, $
	MLT_OUT_LINE: black, MLT_LABEL: black, MLT_DIAL_FILL: 0, $
	LOCAT_MARK: blue, LOCAT_MARK_BG: white, LOCAT_MARK_TXT: $
	blue, HEADER: black, LAT_LINE: black, TXT_CLR: black, $
	CONT_IDX: 0, GLAT_IDX: 0, FOV_EDGE: green}, n_schemes )

conv_ct, 1, 13

ct(1).message = white
ct(1).cbar_plot = white
ct(1).cbar_axis = white
ct(1).cbar_label = white
ct(1).mlt_line = white
ct(1).mlt_out_line = white
ct(1).txt_clr = white
ct(1).header = white
ct(1).lat_line = white
ct(1).cont_idx = 3
ct(1).glat_idx = 3
ct(1).fov_edge = blue

ct(2) = ct(1)
conv_ct, 2, 34

ct(3) = ct(1)
conv_ct, 3, 33

ct(4) = ct(1)
conv_ct, 4, 33, BOT_CLR=[0,0,0], BSTEPS=2

ct(5) = ct(1)
conv_ct, 5, 0, BOT_CLR=[0,0,0], BSTEPS=2

IF NOT DEFINED(cur_ct) THEN cur_ct = 0
TVLCT, ct(cur_ct).rct, ct(cur_ct).gct, ct(cur_ct).bct

RETURN

END

;--------------------------------------------------------------

PRO update_ct, event

COMMON STRUCTURES
COMMON UCOLORS,green,white,blue,red,black,top_color, $
ct,cur_ct,num_schemes

cur_ct = event.index

TVLCT, ct(cur_ct).rct, ct(cur_ct).gct, ct(cur_ct).bct

mop.concolndx = ct( cur_ct ).cont_idx
mop.grdcolndx = ct( cur_ct ).glat_idx

END

;--------------------------------------------------------------

PRO init_calib

COMMON CALIB,dor_trn,cal_pri,cal_sec

dor_trn = [1.0, 0.42, 0.42, 0.5, 0.54, 0.6, 1.0]

cal_pri = [[0.00000, 0.00000, 0.00000, 0.00000, 0.00000], $
           [104856., 69040.9, 16178.0, 19339.2, 467548.], $
           [32188.6, 21194.0, 4966.40, 5936.71, 143527.], $
           [11276.5, 7424.84, 1739.80, 2079.79, 50281.4], $
           [3304.10, 2175.52, 509.790, 609.391, 14732.8], $
           [1824.39, 1201.24, 281.490, 336.482, 8134.86], $
           [454.213, 299.068, 70.0810, 83.7727, 2025.30], $
           [189.559, 124.812, 29.2470, 34.9614, 845.234], $
           [88.5061, 58.2751, 13.6550, 16.3236, 394.642], $
           [34.7352, 22.8707, 5.35940, 6.40639, 154.882], $
           [16.0651, 10.5777, 2.47870, 2.96296, 71.6332], $
           [7.68857, 5.06239, 1.18620, 1.41804, 34.2828], $
           [1.61900, 1.06600, 0.24980, 0.29860, 7.21900], $
           [.405390, 0.26692, 0.06250, 0.07476, 1.80763], $
           [.090501, 0.05959, 0.01395, 0.01669, 0.40354]]

cal_pri = TRANSPOSE(cal_pri)

cal_sec = [[0.00000, 0.00000, 0.00000, 0.00000, 0.00000], $
           [127321., 62534.4, 14864.4, 17965.3, 0.00000], $
           [61454.8, 30183.9, 7174.72, 8671.45, 0.00000], $
           [18202.4, 8940.24, 2125.10, 2568.42, 0.00000], $
           [4852.45, 2383.31, 566.514, 684.695, 0.00000], $
           [2653.04, 1303.06, 309.737, 374.352, 0.00000], $
           [860.102, 422.444, 100.415, 121.363, 0.00000], $
           [412.820, 202.759, 48.1959, 58.2501, 0.00000], $
           [195.276, 95.9109, 22.7980, 27.5540, 0.00000], $
           [71.1447, 34.9431, 8.30599, 10.0387, 0.00000], $
           [34.5806, 16.9845, 4.03721, 4.87942, 0.00000], $
           [16.0025, 7.85974, 1.86826, 2.25800, 0.00000], $
           [3.79000, 1.86146, 0.44246, 0.53477, 7.21900], $
           [1.22975, 0.60399, 0.14357, 0.17352, 0.00000], $
           [0.35836, 0.17601, 0.04184, 0.05056, 0.00000]]

cal_sec = TRANSPOSE(cal_sec)

END

;--------------------------------------------------------------

PRO color_bar,win_id,pos,min,max,IS_PS=is_ps

COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz
COMMON STRUCTURES
COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes
COMMON IMGINFO,filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar

IF KEYWORD_SET(IS_PS) THEN BEGIN
  pos_n = pos
  chr_siz = ps.cbtext
ENDIF ELSE BEGIN
  WSET,win_id
  pos_n = FLTARR(4)
  pos_n( 0 ) = 1.0 * pos( 0 ) / xwin
  pos_n( 1 ) = 1.0 * pos( 1 ) / ywin
  pos_n( 2 ) = 1.0 * pos( 2 ) / xwin
  pos_n( 3 ) = 1.0 * pos( 3 ) / ywin
  chr_siz = charsiz
ENDELSE

;tmp = INDGEN(white+1)
tmp = INDGEN(top_color)
bar = ROTATE( tmp, 1 )

TVimage, bar, position=pos_n, NCOLORS=(SIZE(ct(cur_ct).rct))(1)

; frame color bar
CASE cal_unit OF
 0: unit_lab = '!5photons cm!U-2!N s!U-1!N'
 1: unit_lab = '!5       Rayleighs'
 2: unit_lab = '!5ergs  cm!U-2!N s!U-1!N'
ENDCASE
IF (max GT 999.999) AND (cal_unit EQ 1) THEN BEGIN
  min = 0.001*min
  max = 0.001*max
  unit_lab = '       kR'
ENDIF

IF (scal_value EQ 0) THEN BEGIN
  PLOT,[0,1],[min,max],/YLOG $
      ,POSITION = pos_n, /NORMAL $
      ,/NOERASE,/NODATA $
      ,XTICKS=1,XSTYLE=1,XTICKNAME=[' ',' '] $
      ,YTICKS=1,YTICKNAME=[' ',' '] $
      ,COLOR=ct(cur_ct).cbar_plot $
      ,FONT=5
ENDIF ELSE BEGIN
  PLOT,[0,1],[min,max] $
      ,POSITION = pos_n, /NORMAL $
      ,/NOERASE,/NODATA $
      ,XTICKS=1,XSTYLE=1,XTICKNAME=[' ',' '] $
      ,YTICKS=1,YTICKNAME=[' ',' '] $
      ,COLOR=ct(cur_ct).cbar_plot $
      ,FONT=5
ENDELSE

; !P.POSITION=0
AXIS,YAXIS=1,YRANGE=[min,max],YSTYLE=1,CHARSIZE=chr_siz, $
	COLOR=ct(cur_ct).cbar_axis, TICKLEN=-0.3
ydel = pos_n(3)-pos_n(1)
XYOUTS,pos_n(0) - 0.025*pos_n(0),pos_n(1)+0.25*ydel,unit_lab, $
	ORIENTATION=90.,/NORMAL,COLOR=ct(cur_ct).cbar_label,CHARSIZE=chr_siz

END

;---------------------------------------------------------------
; EVENT PROCEDURES
;---------------------------------------------------------------

PRO studio_event,event

COMMON STRUCTURES
COMMON IMGINFO,filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv
COMMON PRNTINFO,geob,img_format,pict_index,sav_format
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON SEQINFO,beg_seq_rec,end_seq_rec
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag
COMMON SCALE, min_log_scl,max_log_scl,amp,phi

WIDGET_CONTROL, event.id, GET_UVALUE=type

fileqv = [4,3,2,1,5,7,0,6,8] ; list filter number in droplist order

CASE type OF
  0: WIDGET_CONTROL, /DESTROY, event.top
  1: mark_val = event.index
  2: decrement_image
  3: increment_image
  4: roti_val = event.index
  5: ipseq = event.index
  6: filseq = fileqv(event.index)
  7: BEGIN
       cal_unit = event.index
       CASE cal_unit OF
         0: BEGIN                ; photons
              min_log_scl = 3.0
              max_log_scl = 300.0
            END
         1: BEGIN                ; Rayleighs
              min_log_scl = 90.0
              max_log_scl = 9000.0
            END
         2: BEGIN                ; ergs
              min_log_scl = 1.0
              max_log_scl = 100.0
            END
       ENDCASE
       WIDGET_CONTROL, SET_VALUE=min_log_scl, minl
       WIDGET_CONTROL, SET_VALUE=max_log_scl, maxl
     END
  8: WIDGET_CONTROL, GET_VALUE=menu_value, menu
  9: WIDGET_CONTROL, GET_VALUE=enhance, enhs 
 10:
 11: first_image
 12: last_image
 13: BEGIN
       curRec = recnum(event.index)
       WIDGET_CONTROL,event.top,/HOURGLASS
       make_image,curRec
    END
 14: coor_value = event.index
 15: WIDGET_CONTROL, GET_VALUE=beg_seq_rec, brec
 16: WIDGET_CONTROL, GET_VALUE=end_seq_rec, erec
 17: WIDGET_CONTROL, GET_VALUE=show_cbar, cbar
 18: WIDGET_CONTROL, GET_VALUE=scal_value, scal
 20: WIDGET_CONTROL, GET_VALUE=min_log_scl, minl
 21: WIDGET_CONTROL, GET_VALUE=max_log_scl, maxl
 30: WIDGET_CONTROL, GET_VALUE=amp, ampv
 31: WIDGET_CONTROL, GET_VALUE=phi, phiv
 42: update_ct, event
 43: WIDGET_CONTROL, GET_VALUE=img_format, prto
 44: BEGIN
       WIDGET_CONTROL, GET_VALUE=temp, pszw
       ps.cm     = temp
       ps.header = 0.125*temp
       ps.glabel = 0.12*temp
       ps.cbtext = 0.14*temp
       ps.xoff   =  7.0 - 0.25*temp
       ps.yoff   = 10.0 - 0.20*temp
     END
ENDCASE

END

;--------------------------------------------------------------

PRO read_housekeeping,err_flag

COMMON IDS, img_id,orb_id,att_id,dsp_id,dsp_prev_id
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON STRUCTURES

err_flag = 0

img_info=CDF_INQUIRE(img_id)
img_numrecs=img_info.maxrec+1

IF img_numrecs LT 1 THEN BEGIN
  display_message,'No images available...Returning'
  err_flag = 1
  RETURN
ENDIF

ii = REPLICATE({i_info, FILT: BYTE( 0 ), RATE: BYTE( 0 ), GAIN: BYTE( 0 ), $
	DOOR: BYTE( 0 ), SYST: BYTE( 0 ), PFLK: BYTE( 0 ), TBLN: 0.0, $
	NFRM: 0.0, UTHR: 0.0, DSPA: 0.0 }, img_numrecs )

CDF_VARGET,img_id,'FILTER',tmp,REC_COUNT=img_numrecs,COUNT=[1,1,1]
i_filt = REFORM(tmp)

CDF_VARGET,img_id,'FRAMERATE',tmp,REC_COUNT=img_numrecs,COUNT=[1,1,1]
i_rate = REFORM(tmp)

CDF_VARGET,img_id,'GAIN',tmp,REC_COUNT=img_numrecs,COUNT=[1,1,1]
i_gain = REFORM(tmp)

CDF_VARGET,img_id,'DOORPOS',tmp,REC_COUNT=img_numrecs,COUNT=[1,1,1]
i_door = REFORM(tmp)

CDF_VARGET,img_id,'SYSTEM',tmp,REC_COUNT=img_numrecs,COUNT=[1,1,1]
i_syst = REFORM(tmp)

CDF_VARGET,img_id,'PFLCK',tmp,REC_COUNT=img_numrecs,COUNT=[1,1,1]
i_pflk = REFORM(tmp)

; check to see if CDF file contains synch mode images
; current technique is to query whether variable 47 is IMGNUM
var2 = cdf_varinq(img_id,47)
cdf_var = STRTRIM(var2.name)
IF (cdf_var EQ 'IMGNUM') THEN BEGIN
  CDF_VARGET,img_id,'TBLNUM',tmp,REC_COUNT=img_numrecs,COUNT=[1,1,1]
  i_tbln = REFORM(tmp)
  CDF_VARGET,img_id,'NFRM',tmp,REC_COUNT=img_numrecs,COUNT=[1,1,1]
  i_nfrm = REFORM(tmp)
ENDIF ELSE BEGIN
  i_tbln = FLTARR(img_numrecs)
  i_nfrm = FLTARR(img_numrecs)
ENDELSE

ii.filt = i_filt
ii.rate = i_rate
ii.gain = i_gain
ii.door = i_door
ii.syst = i_syst
ii.pflk = i_pflk
ii.tbln = i_tbln
ii.nfrm = i_nfrm

END

;--------------------------------------------------------------

PRO init_orb_time

COMMON IDS, img_id,orb_id,att_id,dsp_id,dsp_prev_id
COMMON ORBIT,orb_gci,att_gci,gc_alt
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON STRUCTURES

orb_info=CDF_INQUIRE(orb_id)
orb_numrecs=orb_info.maxrec+1

; UT time for orbit records
orb_uth = FLTARR(orb_numrecs)
CDF_VARGET,orb_id,'Epoch',dumy,REC_COUNT=orb_numrecs
o_epoch = REFORM(dumy(0,*))
FOR record=0,orb_numrecs-1 DO BEGIN
  CDF_EPOCH,o_epoch(record),yr,mo,dy,hr,mn,sc,/BREAKDOWN_EPOCH
  orb_uth(record) = hr + mn/60. + sc/3600.
ENDFOR

; interpolate to image UT time
o_gci_arr = DBLARR(3,orb_numrecs)
CDF_VARGET,orb_id,'GCI_POS',o_gci_arr,REC_COUNT=orb_numrecs
ogcix = REFORM(o_gci_arr(0,*))
ogciy = REFORM(o_gci_arr(1,*))
ogciz = REFORM(o_gci_arr(2,*))
;o_splx = SPL_INIT(orb_uth,ogcix)
;o_sply = SPL_INIT(orb_uth,ogciy)
;o_splz = SPL_INIT(orb_uth,ogciz)
;ox = SPL_INTERP(orb_uth,ogcix,o_splx,ii.uthr)
;oy = SPL_INTERP(orb_uth,ogciy,o_sply,ii.uthr)
;oz = SPL_INTERP(orb_uth,ogciz,o_splz,ii.uthr)
;orb_gci = FLTARR(3,img_numrecs)
;orb_gci(0,*) = ox
;orb_gci(1,*) = oy
;orb_gci(2,*) = oz
;gc_alt = SQRT(ox*ox + oy*oy + oz*oz)

delt = (orb_uth[orb_numrecs-1]-orb_uth[0])/(orb_numrecs-1.)
j1 = FLOOR((ii.uthr-orb_uth[0])/delt)
j2 = j1 + 1

off = WHERE(j1 LT 0, count)
IF (count GT 0) THEN BEGIN
  j1[off] = 0
  j2[off] = 1
ENDIF
off = WHERE(j2 GE orb_numrecs, count)
IF (count GT 0) THEN BEGIN
  j1[off] = orb_numrecs-2
  j2[off] = orb_numrecs-1
ENDIF

orb_gci = FLTARR(3,img_numrecs)
orb_gci(0,*) = interp2p(orb_uth[j1],orb_uth[j2],ii.uthr, $
               ogcix[j1],ogcix[j2])
orb_gci(1,*) = interp2p(orb_uth[j1],orb_uth[j2],ii.uthr, $
               ogciy[j1],ogciy[j2])
orb_gci(2,*) = interp2p(orb_uth[j1],orb_uth[j2],ii.uthr, $
               ogciz[j1],ogciz[j2])
gc_alt = SQRT(orb_gci[0,*]*orb_gci[0,*] $
            + orb_gci[1,*]*orb_gci[1,*] $
            + orb_gci[2,*]*orb_gci[2,*])

END

;--------------------------------------------------------------

PRO init_att_time

COMMON IDS, img_id,orb_id,att_id,dsp_id,dsp_prev_id
COMMON ORBIT,orb_gci,att_gci,gc_alt
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON STRUCTURES

att_info=CDF_INQUIRE(att_id)
att_numrecs=att_info.maxrec+1

; UT time for attitude file
att_uth = FLTARR(att_numrecs)
CDF_VARGET,att_id,'Epoch',dumy,REC_COUNT=att_numrecs
a_epoch = REFORM(dumy(0,*))
FOR record=0,att_numrecs-1 DO BEGIN
  CDF_EPOCH,a_epoch(record),yr,mo,dy,hr,mn,sc,/BREAKDOWN_EPOCH
  att_uth(record) = hr + mn/60. + sc/3600.
ENDFOR

; interpolate to image UT time
CDF_VARGET,att_id,'GCI_R_ASCENSION',dumy,REC_COUNT=att_numrecs
ra = REFORM(dumy(0,*))
CDF_VARGET,att_id,'GCI_DECLINATION',dumy,REC_COUNT=att_numrecs
dec = REFORM(dumy(0,*))
agcix = COS(dec)*COS(ra) ;x
agciy = COS(dec)*SIN(ra) ;y
agciz = SIN(dec)         ;z
;a_splx = SPL_INIT(att_uth,agcix)
;a_sply = SPL_INIT(att_uth,agciy)
;a_splz = SPL_INIT(att_uth,agciz)
;ax = SPL_INTERP(att_uth,agcix,a_splx,ii.uthr)
;ay = SPL_INTERP(att_uth,agciy,a_sply,ii.uthr)
;az = SPL_INTERP(att_uth,agciz,a_splz,ii.uthr)
;att_gci = FLTARR(3,img_numrecs)
;att_gci(0,*) = ax
;att_gci(1,*) = ay
;att_gci(2,*) = az

delt = (att_uth[att_numrecs-1]-att_uth[0])/(att_numrecs-1.)
j1 = FLOOR((ii.uthr-att_uth[0])/delt)
j2 = j1 + 1

off = WHERE(j1 LT 0, count)
IF (count GT 0) THEN BEGIN
  j1[off] = 0
  j2[off] = 1
ENDIF
off = WHERE(j2 GE att_numrecs, count)
IF (count GT 0) THEN BEGIN
  j1[off] = att_numrecs-2
  j2[off] = att_numrecs-1
ENDIF

att_gci = FLTARR(3,img_numrecs)
att_gci(0,*) = interp2p(att_uth[j1],att_uth[j2],ii.uthr, $
               agcix[j1],agcix[j2])
att_gci(1,*) = interp2p(att_uth[j1],att_uth[j2],ii.uthr, $
               agciy[j1],agciy[j2])
att_gci(2,*) = interp2p(att_uth[j1],att_uth[j2],ii.uthr, $
               agciz[j1],agciz[j2])

END

;--------------------------------------------------------------

PRO openFile, img_file

COMMON WINDINFO,main_windex,xmsg,ymsg,imsg,orbit_windex,model_windex
COMMON IDS, img_id,orb_id,att_id,dsp_id,dsp_prev_id
COMMON ORBIT,orb_gci,att_gci,gc_alt
COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON SEQINFO,beg_seq_rec,end_seq_rec
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag
COMMON STRUCTURES

;img_file=PICKFILE(PATH=path.img,FILTER='*.cdf',GET_PATH=path.img,$
;  TITLE='Please Select Image File')

str_len = STRLEN(img_file)
IF (str_len GT 3) THEN extension = STRMID(img_file,str_len-3,3) $
ELSE RETURN
IF (extension EQ 'cdf') OR (extension EQ 'CDF') THEN $
  img_id = CDF_OPEN(img_file) ELSE RETURN

spos = STRPOS(img_file,'uvi_')
yyyymmdd = STRMID(img_file,spos+4,8)

get_oa_files,yyyymmdd,orb_file,att_file

; get file ids
orb_id = get_file_id(orb_file)

IF (orb_id LE 0) THEN BEGIN
  display_message,'error reading orbit file',/erase_screen
  print,'file:'+orb_file
  display_message,'file id:'+STRING(orb_id)
  display_message,'program stopping....'
  WAIT,2.0
  STOP
ENDIF
att_id = get_file_id(att_file)
IF (att_id LE 0) THEN BEGIN
  display_message,'error reading attitude file',/erase_screen
  print,'file:'+att_file
  display_message,'file id:'+STRING(att_id)
  display_message,'program stopping....'
  WAIT,2.0
  STOP
ENDIF
WSET, main_windex

file_flag = 1
list_flag = 0
seqc_flag = 0

; read housekeeping parameters from the image file
display_message,'reading housekeeping.....',/erase_screen
read_housekeeping,err_flag
IF err_flag THEN RETURN

; structure for image frame
display_message,'initializing frame time....'

ft = REPLICATE({frame_time, YEAR: 0, MONTH: 0, DAY: 0, HOUR: 0, $
   MINUTE: 0, SECOND: 0, DOY: 0, DOP: 0},img_numrecs)
FOR record=0,img_numrecs-1 DO get_frm_time,img_id,record,ii(record).rate

; create ut hour array for image file
ii.uthr = ft.hour + ft.minute/60. + ft.second/3600.
pre = 0
IF (ft(0).dop LT ft(img_numrecs-1).dop) THEN BEGIN
  pre = 1
  i = 0
  WHILE ii(i).uthr LT ii(i+1).uthr DO BEGIN
    ii(i).uthr = ii(i).uthr - 24.
    i = i + 1
  ENDWHILE
  ii(i).uthr = ii(i).uthr - 24.
ENDIF

; orbit file parameters
display_message,'initializing orbit time....'
init_orb_time

; attitude file parameters
display_message,'initializing attitude time....'
init_att_time

;display_message,'creating background image....'
;dum = MAX(gc_alt,apogee_record) ; find apogee record
;make_background,apogee_record

display_message,'reading dsp angles....'
psl = 0
get_dsp_files,img_file,dsp_file,dsp_prev_file,pre=pre,psl=psl
;IF psl THEN get_psl_angles,yyyymmdd,psl_ang ELSE BEGIN
  dsp_id = get_file_id(dsp_file)
  IF (dsp_id EQ -1) THEN BEGIN
    display_message,'error reading dsp file',/erase_screen
    STOP
  ENDIF
  IF pre THEN BEGIN
    dsp_prev_id = get_file_id(dsp_prev_file)
    IF (dsp_prev_id EQ -1) THEN BEGIN
      display_message,'error reading previous dsp file',/erase_screen
      print,'file:'+dsp_prev_file
      display_message,'file id:'+STRING(dsp_prev_id)
      display_message,'program stopping....'
      WAIT,2.0
      STOP
    ENDIF
  ENDIF
  get_dsp_angles,pre=pre
;ENDELSE

display_message,'creating image list....'
create_image_list,error
IF error THEN RETURN

; time_limits
begRec = 0
endRec = img_numrecs-1

; set the current record to the first image of the image list
curRec = recnum[0]
make_image,curRec

; initialize the sequence record display with the
; beginning and end records
beg_seq_rec = begRec
end_seq_rec = endRec
WIDGET_CONTROL, brec, SET_VALUE=STRING(beg_seq_rec,FORMAT='(I4.4)')
WIDGET_CONTROL, erec, SET_VALUE=STRING(end_seq_rec,FORMAT='(I4.4)')

END

;--------------------------------------------------------------

PRO get_sequence_event,event

COMMON SEQINFO,beg_seq_rec,end_seq_rec
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag

IF NOT (file_flag) THEN BEGIN
  filw = WIDGET_MESSAGE('Please select file first!')
  RETURN
ENDIF

; build compound widget
sbas = WIDGET_BASE(COLUMN=1,TITLE='Select Sequence')
brid = CW_FIELD(sbas,TITLE='Start Record:',VALUE=beg_seq_rec $
             ,/INTEGER,/RETURN_EVENTS)
erid = CW_FIELD(sbas,TITLE='End Record:',VALUE=end_seq_rec $
             ,/INTEGER,/RETURN_EVENTS)

; realize base and start event handler for this base
WIDGET_CONTROL,sbas,/REALIZE
sevn = WIDGET_EVENT(sbas)

; the return key was hit.  read values and then
; get rid of text widget
WIDGET_CONTROL, brid, GET_VALUE=erec_array
WIDGET_CONTROL, erid, GET_VALUE=brec_array
WIDGET_CONTROL, sbas, /DESTROY

; reformat values read from text widget
beg_seq_rec = brec_array(0)
end_seq_rec = erec_array(0)

seqc_flag = 1

END

;--------------------------------------------------------------

PRO run_sequence_event,event

COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON SEQINFO,beg_seq_rec,end_seq_rec
COMMON PRNTINFO,geob,img_format,pict_index,sav_format
COMMON STRUCTURES

IF NOT (file_flag) THEN BEGIN
  filw = WIDGET_MESSAGE('Please select file first!')
  RETURN
ENDIF

WIDGET_CONTROL,rnsq,SET_VALUE='Cancel'
WIDGET_CONTROL,rnsq,EVENT_PRO='stop_event'

run_flag = 1
record = beg_seq_rec
WHILE (run_flag) DO BEGIN
  IF(record LE end_seq_rec) THEN BEGIN
    check_image,record,show_frame
    IF show_frame THEN BEGIN
      curRec = record
      make_image,record
    ENDIF
    record = record + 1
  ENDIF ELSE run_flag = 0
  dest = WIDGET_EVENT(rnsq,/NOWAIT)
ENDWHILE
run_flag = 0

WIDGET_CONTROL,rnsq,SET_VALUE='Run Sequence'
WIDGET_CONTROL,rnsq,EVENT_PRO='run_sequence_event'

;save polar cap area arrays only after finished w/images
IF sav_format(5) THEN BEGIN
  remove = where(pc(*).area GT 0, count)
  IF count GT 0 THEN BEGIN
    area = pc(remove).area
    ut = pc(remove).ut
    pcafile = path.sav + $
              STRMID(make_filetag(beg_seq_rec),0,15)+ $
              STRMID(make_filetag(curRec),8,7)+'_pca.sav'
    PRINT, 'Saving file: ',pcafile
    SAVE, ut, area, FILE=pcafile
  ENDIF ELSE PRINT, 'No area.'
ENDIF

;save hemispheric power only after finished w/images
IF sav_format(7) THEN BEGIN
  keep = where(ap(*).power GT 0, count)
  IF count GT 0 THEN BEGIN
    ut = ap(keep).ut
    power = ap(keep).power
    ap_file = path.sav + $
              STRMID(make_filetag(beg_seq_rec),0,15)+ $
              STRMID(make_filetag(curRec),8,7)+'_ap.sav'
  SAVE,ut,power,FILE=ap_file
  PRINT,'Saved ',ap_file,'......'
  ENDIF ELSE PRINT,'No power available ....'
ENDIF

END

;--------------------------------------------------------------

PRO model_dayglow_event,event

COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz
COMMON CONSTANTS,earth_radius
COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON STRUCTURES
COMMON AUXIL
COMMON ORBIT,orb_gci,att_gci,gc_alt
COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes
COMMON IMAGES,raw_img
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag
COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv
COMMON SEQINFO,beg_seq_rec,end_seq_rec
COMMON SCALE, min_log_scl,max_log_scl,amp,phi
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON WINDINFO,main_windex,xmsg,ymsg,imsg,orbit_windex,model_windex
COMMON MODEL,empmod

IF NOT (file_flag) THEN BEGIN
  filw = WIDGET_MESSAGE('Please select file first!')
  RETURN
ENDIF

WIDGET_CONTROL,dglo,SET_VALUE='Cancel'
WIDGET_CONTROL,dglo,EVENT_PRO='stop_event'

PRINT,'WARNING: dayglow modeling fails for linear color scale!'

;nangle = 151
nangle =  181
empmod = FLTARR(nangle)
dayglo = FLTARR(nangle)
nitems = LONARR(nangle)
szang = FINDGEN(nangle)
szamin = 0
;szamax = 150
szamax =  180
mask = INTARR(nxpix,nypix)
mask(WHERE(bkg_img GT 0.1)) = 1

IF DEFINED(model_windex) THEN WSET, model_windex ELSE $
  WINDOW,/FREE,XSIZE=300,YSIZE=250,TITLE='Data Model'
model_windex = !D.WINDOW

record = beg_seq_rec
WHILE (record LE end_seq_rec) DO BEGIN

  ; cancel event if button pushed
  dest = WIDGET_EVENT(dglo,/NOWAIT)

  check_image,record,show_frame 
  IF show_frame THEN get_calibrated_image,record,cal_img,img_flag $
    ELSE img_flag = 0

  IF show_frame AND img_flag THEN BEGIN
    PRINT,'processing record',record,' ....'

    ; get orbit and attitude vectors
    o_gci = REFORM(orb_gci(*,record))
    a_gci = REFORM(att_gci(*,record))

    system = ii(record).syst + 1

    ; Determine time array (must be type long)
    time = LONARR(2)
    time(0) = 1000L*ft(record).year + ft(record).doy
    time(1) = (ft(record).hour*3600L + ft(record).minute*60L $
         + ft(record).second)*1000L
 
    ; produce rotation matrix: gci -> geo coordinates
    ic_gci_to_geo,time,rotm
 
    uvilook,time,o_gci,a_gci,ii(record).dspa,ii(record).filt, $
        versStr,l0,ra,dec,system=system

    ; create lat lon files
    ptg,system,time,l0,a_gci,o_gci,emis_hgt,lat,lon,/geodetic
    latstr = STRING(lat(99,113),FORMAT='(F7.2)')
    lonstr = STRING(lon(99,113),FORMAT='(F7.2)')
;    PRINT,'Center of FOV: (lat,lon) = (',latstr,',',lonstr,')'

    ; find the lat and lon for the subsatellite point
    o_geo = TRANSPOSE(TRANSPOSE(rotm) # o_gci)
    o_geo = unit_vec(o_geo)
    sslat = ASIN(o_geo(2))/!DTOR
    sslon = ATAN(o_geo(1),o_geo(0))/!DTOR
    latstr = STRING(sslat,FORMAT='(F7.2)')
    lonstr = STRING(sslon,FORMAT='(F7.2)')
;    PRINT,'Subsat pt.: (lat,lon) = (',latstr,',',lonstr,')'

;    PRINT,'find the LOS correction for all pixels.....'
    ; find the LOS correction for all pixels
    rsat = vec_norm(o_gci)
;    PRINT,'rsat ',rsat,rsat/earth_radius
;    los_corr,rsat,sslat,sslon,lat,lon,los
    area_los,rsat,sslat,sslon,lat,lon,system,area,los,inv_los

;    PRINT,'find the solar zenith angle for all pixels....'
    ; find the solar zenith angle for all pixels
    ut = ii(record).uthr
    year = FIX(ft(record).year)
    month = FIX(ft(record).month)
    day = FIX(ft(record).day)
    get_sza,ut,year,month,day,lat,lon,sza

;    PRINT,'convert to magnetic coordinates...' 
    ; convert to apex magnetic coordinates
    geo_to_apex,lat,lon,lat_mag,lon_mag,apexfile 
    utsec = 3600L*ft(record).hour + 60L*ft(record).minute + ft(record).second
    mlt = get_mlt(ft(record).year,ft(record).doy,utsec,lon_mag,sslon)

    day_upper_bound = 75.
;    day_upper_bound = 90.
    day_lower_bound = -75.
    nit_upper_bound = 70.
;    nit_upper_bound = 90.
    nit_lower_bound = -70.
    count = 0L
    dayndx = WHERE(mlt LE 18. AND mlt GT 6. AND $
                   lat_mag LT day_upper_bound AND $
                   lat_mag GE day_lower_bound AND $
                   mask EQ 1,count1)
    nitndx = WHERE(mlt LE 6. OR mlt GT 18. AND $
                   lat_mag LT nit_upper_bound AND $
                   lat_mag GE nit_lower_bound AND $
                   mask EQ 1,count2)
; *** fix bug here ***
; *** if either dayndx or nitndx = -1, ***
; *** then program fails ***
; *** M. Fillingim 7/31/03
;    magndx = [dayndx,nitndx]
;    count = 0L
;    count = count1 + count2
    IF (count1 GT 0) THEN magndx = dayndx
    IF (count2 GT 0) THEN magndx = nitndx
    IF (count1 GT 0 AND count2 GT 0) THEN magndx = [dayndx, nitndx]
    count = count1 + count2

    ; bin dayglow array
    i = 0L
    j = 0L
    max_flux = 100.
    IF (count GT 0L) THEN BEGIN
      FOR i=0L,count-1L DO BEGIN
        j = FLOOR(sza(magndx(i)))
        flux = cal_img(magndx(i))
;        IF (flux LT max_flux AND J LT 110) THEN BEGIN
          dayglo(j) = dayglo(j) + flux/los(magndx(i))
          nitems(j) = nitems(j) + 1
;        ENDIF
      ENDFOR 
    ENDIF

    ; use a temporary copy of nitems and replace 0's with 1 
    pitems = nitems > 1

    ; create empirical model
    empmod = dayglo/pitems

    ; remove extreme deviates
;    limit = 3
 ;   temp = empmod
 ;   FOR k=2,nangle-3 DO BEGIN
 ;    nbhd_avg = (TOTAL(empmod(k-2:k+2)) - empmod(k))/4.
 ;     IF (ABS(empmod(k)-nbhd_avg) GT limit) THEN temp(k) = nbhd_avg
 ;   ENDFOR
 ;;   empmod = temp

    PLOT,szang,empmod,PSYM=4, $
       XRANGE=[szamin,szamax],XSTYLE=1,YRANGE=[0,75], $
       xtitle='Solar Zenith Angle', $
       ytitle='Model Photon Flux',COLOR=black

  ENDIF

  ; increment record
  record = record + 1

ENDWHILE

domod = 1
IF (domod) THEN BEGIN

  model = amp*cos(phi*szang*!DTOR)^2
; *** fix the upswing in the model for SZAs ***
; *** between 90 and 110 when phi > 0.82 ***
; *** regions of positive slope in the model are set to zero ***
; *** M. Fillingim 7/71/03
  dum = MIN(model, subs)
  model[subs:150] = 0.
  PLOT,szang,empmod,PSYM=4, $
    XRANGE=[0,150],XSTYLE=1,YRANGE=[0,75], $
    xtitle='Solar Zenith Angle', $
    ytitle='Model Photon Flux',COLOR=black
;  OPLOT,szang,model,linestyle=0,COLOR=red
  refresh_model_event

  date_str = STRMID(make_filetag(recnum[0]),0,8)
  sav_filename = path.sav + date_str + '_dg.sav'
  PRINT,'Saving File: ',sav_filename,'.....'
  SAVE,szang,model,filename=sav_filename

ENDIF

WIDGET_CONTROL,dglo,SET_VALUE='Model Dayglow'
WIDGET_CONTROL,dglo,EVENT_PRO='model_dayglow_event'

END

;--------------------------------------------------------------

PRO refresh_model_event, event

COMMON SCALE, min_log_scl,max_log_scl,amp,phi
COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes
COMMON WINDINFO,main_windex,xmsg,ymsg,imsg,orbit_windex,model_windex
COMMON MODEL,empmod

WSET, model_windex
ERASE

nangle = 151
szang = FINDGEN(nangle)
model = amp*cos(phi*szang*!DTOR)^2
; *** fix the upswing in the model for SZAs ***
; *** between 90 and 110 when phi > 0.82 ***
; *** points with SZAs larger than SZA of model minimum set to zero ***
; *** M. Fillingim 7/71/03
;model[111:150] = 0.
dum = MIN(model, subs)
model[subs:150] = 0.
PLOT,szang,empmod,PSYM=4, $
    XRANGE=[0,150],XSTYLE=1,YRANGE=[0,75], $
    xtitle='Solar Zenith Angle', $
    ytitle='Model Photon Flux',COLOR=black
OPLOT,szang,model,linestyle=0,COLOR=red

END 

;--------------------------------------------------------------
; PROCEDURES
;--------------------------------------------------------------

PRO create_image_list,error

COMMON STRUCTURES
COMMON ORBIT,orb_gci,att_gci,gc_alt
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag
COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv

; cancel this procedure if no file was selected
IF NOT (file_flag) THEN BEGIN
  filw = WIDGET_MESSAGE('Please select file first')
  RETURN
ENDIF

; find valid images, on error return
; *** include HOME and SHUT images ***
;recnum = WHERE((ii.filt GT 0) AND (ii.filt LE 5) $
recnum = WHERE((ii.filt GE 0) AND (ii.filt LE 6) $
; *** include low gain images ***
;            AND ii.gain GT 10, valid_images)
            AND ii.gain GT 0, valid_images)
IF (valid_images LE 0) THEN BEGIN
  display_message,'No images available.....',/erase_screen
  error = 1
  RETURN
ENDIF

nimgs = (SIZE(recnum))(1)
begRec = recnum(0)
endRec = recnum(nimgs-1)

lb = REPLICATE({labels, YEAR_STR: '00', MONTH_STR: '00', DAY_STR: '00', $
                HOUR_STR: '00', MINUTE_STR: '00', SECOND_STR: '00', $
                FILTER_STR: 'XXXX', IP_STR: 'XX.X', DSP_STR: '-XXX.X', $
                GAIN_STR: 'XX', DOOR_STR: 'XXXXXX', RECORD_STR: 'XXXX'}, $
                nimgs)

pc = REPLICATE({pcarea, AREA: 0., UT: 0.}, img_numrecs)
ap = REPLICATE({power, POWER: 0., UT: 0.}, img_numrecs)

pos = 0

; Put this loop in to prevent an error that occurs when processing 
; too many records at once.
WHILE pos LT nimgs DO BEGIN
  imgs_left = nimgs - pos
  IF imgs_left GT 1023 THEN imgs_left = 1023

  last_img = imgs_left + pos
  rec_lst = recnum(pos:last_img-1)

  lb(pos:last_img-1).year_str = $
	  STRING(ft(rec_lst).year,FORMAT='(I4.4)')
  lb(pos:last_img-1).month_str = $
	  STRING(ft(rec_lst).month,FORMAT='(I2.2)')
  lb(pos:last_img-1).day_str = $
	  STRING(ft(rec_lst).day,FORMAT='(I2.2)')
  lb(pos:last_img-1).hour_str = $
	  STRING(ft(rec_lst).hour,FORMAT='(I2.2)')
  lb(pos:last_img-1).minute_str = $
	  STRING(ft(rec_lst).minute,FORMAT='(I2.2)')
  lb(pos:last_img-1).second_str = $
	  STRING(ft(rec_lst).second,FORMAT='(I2.2)')
  lb(pos:last_img-1).dsp_str = $
	  STRING(ii(rec_lst).dspa,FORMAT='(F8.3)')
  lb(pos:last_img-1).gain_str = $
	  STRING(ii(rec_lst).gain,FORMAT='(I2.2)')
  lb(pos:last_img-1).record_str = $
	  STRING(rec_lst,FORMAT='(I4.4)')

  pos = last_img
ENDWHILE

; filters
sub_fil = ii(recnum).filt
; *** inlcude HOME and SHUT images ***
qindx = WHERE(sub_fil EQ 0,count)
IF (count GT 0) THEN lb(qindx).filter_str = 'HOME'
; ***
qindx = WHERE(sub_fil EQ 1,count)
IF (count GT 0) THEN lb(qindx).filter_str = '1304'
qindx = WHERE(sub_fil EQ 2,count)
IF (count GT 0) THEN lb(qindx).filter_str = '1356'
qindx = WHERE(sub_fil EQ 3,count)
IF (count GT 0) THEN lb(qindx).filter_str = 'LBHS'
qindx = WHERE(sub_fil EQ 4,count)
IF (count GT 0) THEN lb(qindx).filter_str = 'LBHL'
qindx = WHERE(sub_fil EQ 5,count)
IF (count GT 0) THEN lb(qindx).filter_str = 'SOLR'
; *** inlcude HOME and SHUT images ***
qindx = WHERE(sub_fil EQ 6,count)
IF (count GT 0) THEN lb(qindx).filter_str = 'SHUT'
; ***

; integration period
sub_ipd = ii(recnum).rate
qindx = WHERE(sub_ipd EQ 1,count)
IF (count GT 0) THEN lb(qindx).ip_str = ' 9.2'
qindx = WHERE(sub_ipd EQ 2,count)
IF (count GT 0) THEN lb(qindx).ip_str = '18.4'
qindx = WHERE(sub_ipd EQ 4,count)
IF (count GT 0) THEN lb(qindx).ip_str = '36.8'
sub_ipd = ii(recnum).nfrm
qindx = WHERE(sub_ipd EQ 1,count)
IF (count GT 0) THEN lb(qindx).ip_str = ' 1.5'
qindx = WHERE(sub_ipd EQ 2,count)
IF (count GT 0) THEN lb(qindx).ip_str = ' 3.0'

; door position
sub_dor = ii(recnum).door
qindx = WHERE(sub_dor EQ 1,count)
IF (count GT 0) THEN lb(qindx).door_str = ' open '
qindx = WHERE(sub_dor EQ 2,count)
IF (count GT 0) THEN lb(qindx).door_str = ' open '
qindx = WHERE(sub_dor EQ 3,count)
IF (count GT 0) THEN lb(qindx).door_str = 'closed'

lisstr = lb.hour_str + lb.minute_str + ':' + lb.second_str + ' ' $
       + lb.filter_str + ' ' + lb.ip_str + lb.dsp_str + ' ' $
       + lb.record_str

;OPENW, outf_num, 'image_lst', /GET_LUN
;
;count = (SIZE( lisstr ))(1)
;
;FOR i=0, count-1 DO BEGIN
;  PRINTF, outf_num, lisstr(i)
;ENDFOR
;
;FREE_LUN, outf_num

WIDGET_CONTROL,wlst,SET_VALUE=lisstr

list_flag = 1
error = 0

END

;--------------------------------------------------------------

PRO selectFile_event, event

COMMON SFIDS,yydl,mmdl,dddl,ymd
COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv

yy_dplist = ['1996','1997','1998','1999','2000','2001','2002','2003', $
             '2004', '2005', '2006', '2007']
;mm_dplist = STRING(INDGEN(12)+1)
mm_dplist = ['Jan','Feb','Mar','Apr','May','Jun', $
             'Jul','Aug','Sep','Oct','Nov','Dec']
dd_dplist = STRING(INDGEN(31)+1)

; file select inititialization
ymd = ['1996','01','01']

; base
sfeb = WIDGET_BASE(/COLUMN,TITLE='Select Date',GROUP_LEADER=base)
row1 = WIDGET_BASE(sfeb,/ROW)
col1 = WIDGET_BASE(row1,/COLUMN)
yylb = WIDGET_LABEL(col1,VALUE='Year')
yydl = WIDGET_DROPLIST(col1,UVALUE=51,VALUE=yy_dplist)
col2 = WIDGET_BASE(row1,/COLUMN)
mmlb = WIDGET_LABEL(col2,VALUE='Month')
mmdl = WIDGET_DROPLIST(col2,UVALUE=52,VALUE=mm_dplist)
col3 = WIDGET_BASE(row1,/COLUMN)
ddlb = WIDGET_LABEL(col3,VALUE='Day')
dddl = WIDGET_DROPLIST(col3,UVALUE=53,VALUE=dd_dplist)
row2 = WIDGET_BASE(sfeb,/ROW)
exeb = WIDGET_BUTTON(row2,UVALUE=50,VALUE='Get File')
srcb = WIDGET_BUTTON(row2,UVALUE=54,VALUE='Browse')
nrtb = WIDGET_BUTTON(row2,UVALUE=55,VALUE='NRT File')
quib = WIDGET_BUTTON(row2,UVALUE=99,VALUE='Cancel')

; realize base and hand-off control to the map options event manager
WIDGET_CONTROL,sfeb,/REALIZE
XMANAGER, 'getFile', sfeb

END

;--------------------------------------------------------------

PRO getFile_event, event

COMMON SFIDS,yydl,mmdl,dddl,ymd
COMMON STRUCTURES

WIDGET_CONTROL, event.id, GET_UVALUE=type

yy_dplist = ['1996','1997','1998','1999','2000','2001','2002','2003', $
             '2004', '2005', '2006', '2007']
mm_dplist = STRING(INDGEN(12)+1,FORMAT='(I2.2)')
dd_dplist = STRING(INDGEN(31)+1,FORMAT='(I2.2)')

CASE type OF
  50: BEGIN
        strTmp = path.img+'po_l1_uvi_' + ymd(0)+ymd(1)+ymd(2) + '*.cdf' 
        tmp_img_fil = FINDFILE(strTmp, COUNT=count)
        IF count EQ 0 THEN BEGIN
          img_file = fileChooser(path=path.img,filter='*.cdf', $
                                 title='Image File')
        ENDIF ELSE BEGIN
          ;Sort the definitive orbit files in descending order so that
          ;the latest file is first
          tmp_img_fil = tmp_img_fil(REVERSE(SORT(tmp_img_fil)))
          ;Use the latest file
          img_file = tmp_img_fil(0)
        ENDELSE
        IF (img_file NE '') THEN BEGIN
          WIDGET_CONTROL, /DESTROY, event.top
          openFile, img_file
        ENDIF
      END
  51: ymd(0) = yy_dplist(event.index) 
  52: ymd(1) = mm_dplist(event.index)
  53: ymd(2) = dd_dplist(event.index)
  54: BEGIN
        img_file = fileChooser(path=path.img,filter='*.cdf', $
                               title='Image File')
        IF (img_file NE '') THEN BEGIN
          WIDGET_CONTROL, /DESTROY, event.top
          openFile, img_file
        ENDIF
      END
  55: BEGIN
        img_file = fileChooser(path=path.nrt,filter='*.cdf', $
                               title='Image File')
        IF (img_file NE '') THEN BEGIN
          WIDGET_CONTROL, /DESTROY, event.top
          openFile, img_file
        ENDIF
      END
  99: WIDGET_CONTROL, /DESTROY, event.top
ENDCASE

END

;--------------------------------------------------------------

PRO mapop_event, event

COMMON MAPIDS,shwm,lats,lons,lims,sib4,strw,nywf,nzwf
COMMON STRUCTURES
COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes
COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv

show_items = ['Continents','Gridlines','Labels']
show_value = [mop.putcon,mop.putgrd,mop.putlab]
con_dplist = ['black','blue','red','white','green']
grd_dplist = ['black','blue','red','white','green']
lat_dplist = [' 10  ',' 20  ','  5  ']
lon_dplist = [' 45  ',' 20  ',' 10  ','  5  ']
mlt_opts = ['FOV edge']
lim_dplist = [' 60 ', ' 50 ', ' 40 ', ' 30 ', ' 20 ', ' 10 ', ' 0 ']
star_items = ['Show Stars','Correct Boresight']

; base
basl = WIDGET_BASE(/COL,TITLE='Plot Options',GROUP_LEADER=base)
bas0 = WIDGET_BASE(basl,/ROW,TITLE='Quit',FRAME=5)
bas1 = WIDGET_BASE(basl,/ROW,TITLE='Geographic',FRAME=5)
bas2 = WIDGET_BASE(basl,/ROW,TITLE='MLT',FRAME=5)
bas3 = WIDGET_BASE(basl,/COL,TITLE='Stars',FRAME=5)

; sibling0
quib = WIDGET_BUTTON(bas0,UVALUE=99,VALUE='Close')

; sibling1
sib1 = WIDGET_BASE(bas1,/COLUMN)
shwm = CW_BGROUP(sib1,UVALUE=14,/COLUMN,/NONEXCLUSIVE,show_items, $
  SET_VALUE=show_value)

;sibling 2
sib2 = WIDGET_BASE(bas1,/COLUMN)
coll = WIDGET_LABEL(sib2,VALUE='  COLOR  ')
cont = WIDGET_LABEL(sib2,VALUE='Continents')
cond = WIDGET_DROPLIST(sib2,UVALUE=15,VALUE=con_dplist)
cont = WIDGET_LABEL(sib2,VALUE='   Grid   ')
grdd = WIDGET_DROPLIST(sib2,UVALUE=16,VALUE=grd_dplist)

;sibling 3
sib3 = WIDGET_BASE(bas1,/COLUMN)
grds = WIDGET_LABEL(sib3,VALUE='GRID SPACING')
lats = CW_FIELD(sib3,UVALUE=17,TITLE='Latitude',VALUE=mop.latdel, $
  XSIZE=8,/COLUMN,/INTEGER,/ALL_EVENTS)
lons = CW_FIELD(sib3,UVALUE=18,TITLE='Longitude',VALUE=mop.londel, $
  XSIZE=8,/COLUMN,/INTEGER,/ALL_EVENTS)

; sibling 4
lims = WIDGET_DROPLIST(bas2,UVALUE=19,VALUE=lim_dplist)
sib4 = CW_BGROUP(bas2,UVALUE=20,/COLUMN,/NONEXCLUSIVE,mlt_opts, $
  SET_VALUE=mop.fov)

; sibling 5
strw = CW_BGROUP(bas3,UVALUE=30,/COLUMN,/NONEXCLUSIVE,star_items, $
  SET_VALUE=mop.stars)
sib5 = WIDGET_BASE(bas3,/ROW,TITLE='Correct Boresight')
nywf = CW_FIELD(sib5,UVALUE=41,TITLE='Ny',VALUE=mop.ny, $
  XSIZE=5,/ROW,/INTEGER,/ALL_EVENTS)
nzwf = CW_FIELD(sib5,UVALUE=42,TITLE='Nz',VALUE=mop.nz, $
  XSIZE=5,/ROW,/INTEGER,/ALL_EVENTS)

; realize base and hand-off control to the map options event manager
WIDGET_CONTROL,basl,/REALIZE
XMANAGER, 'mapwin', basl

END

;--------------------------------------------------------------

PRO mapwin_event, event

COMMON MAPIDS,shwm,lats,lons,lims,sib4,strw,nywf,nzwf
COMMON STRUCTURES

WIDGET_CONTROL, event.id, GET_UVALUE=type
temp = 0
limval = [60, 50, 40, 30, 20, 10, 0]

CASE type OF
14: BEGIN
      WIDGET_CONTROL, GET_VALUE=show_val, shwm
      mop.putcon = show_val(0)
      mop.putgrd = show_val(1)
      mop.putlab = show_val(2)
    END
15: mop.concolndx = event.index
16: mop.grdcolndx = event.index
17: BEGIN
      WIDGET_CONTROL, GET_VALUE = temp, lats
      mop.latdel = temp
    END
18: BEGIN
      WIDGET_CONTROL, GET_VALUE = temp, lons
      mop.londel = temp
    END
19: BEGIN
      mop.latmin = limval(event.index)
    END
20: BEGIN
      WIDGET_CONTROL, GET_VALUE = temp, sib4
      mop.fov = temp
    END
30: BEGIN
      WIDGET_CONTROL, GET_VALUE=temp, strw
      mop.stars = temp
    END
41: BEGIN
      WIDGET_CONTROL, GET_VALUE=temp, nywf
      mop.ny = temp(0)
    END
42: BEGIN
      WIDGET_CONTROL, GET_VALUE=temp, nzwf
      mop.nz = temp(0)
    END
99: WIDGET_CONTROL, /DESTROY, event.top
ENDCASE

END

;--------------------------------------------------------------

PRO save_event,event

COMMON PRNTINFO,geob,img_format,pict_index,sav_format
COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv

save_items = ['Image, Lat & Lon','Image, MLat & MLT', $
              'MLT Keogram Data','Calibrated Image ', $
              'MLT Transform Image','Polar Cap Area', $
              'FAST path flux','Auroral Power', 'Structure']
; *** add save structure option ***
;              'FAST path flux','Auroral Power']
;              'FAST path flux','Auroral Power', 'Structure']
; ***

; orphan 2
orp2 = WIDGET_BASE(/COLUMN,TITLE='Select Options',GROUP_LEADER=base)

; sibling 1
sib1 = WIDGET_BASE(orp2,/COLUMN)
geol = WIDGET_LABEL(sib1,VALUE='Export Options')
geob = CW_BGROUP(sib1,UVALUE=30,/COLUMN,/NONEXCLUSIVE,save_items, $
         SET_VALUE=sav_format)
quib = WIDGET_BUTTON(sib1,UVALUE=32,VALUE='Close')

; realize base and hand-off control to the print options event manager
WIDGET_CONTROL,orp2,/REALIZE
XMANAGER, 'savformat', orp2

END

;--------------------------------------------------------------

PRO savformat_event,event

COMMON PRNTINFO,geob,img_format,pict_index,sav_format

WIDGET_CONTROL, event.id, GET_UVALUE=type

CASE type OF
  30: BEGIN
        WIDGET_CONTROL, GET_VALUE=read_val, geob
        sav_format = read_val
      END
  32: WIDGET_CONTROL, /DESTROY, event.top
ENDCASE

END

;--------------------------------------------------------------

PRO path_event,event

COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv
COMMON EDIT_PATHS,selected_path,ptxt,slpb,paths
COMMON STRUCTURES

paths = [path.psc,path.sav,path.gif]
path_items = ['Postscript','IDL SAV files','GIF']

; orphan 3
orp3 = WIDGET_BASE(/COLUMN,TITLE='Path Editor',GROUP_LEADER=base)

; sibling 1
sib6 = WIDGET_BASE(orp3,/COLUMN)
quib = WIDGET_BUTTON(sib6,UVALUE=40,VALUE='Close')
slpb = CW_BGROUP(sib6,UVALUE=41,/COLUMN,/EXCLUSIVE,path_items, $
         SET_VALUE=selected_path)
ptxt = CW_FIELD(sib6,UVALUE=42,TITLE='path:',VALUE=paths(selected_path), $
            XSIZE=20,/STRING,/ALL_EVENTS)

; realize base and hand-off control to the print options event manager
WIDGET_CONTROL,orp3,/REALIZE
XMANAGER, 'pathedit', orp3

END

;--------------------------------------------------------------

PRO pathedit_event,event

COMMON EDIT_PATHS,selected_path,ptxt,slpb,paths
COMMON STRUCTURES

WIDGET_CONTROL, event.id, GET_UVALUE=type

CASE type OF
  40: WIDGET_CONTROL, /DESTROY, event.top
  41: BEGIN
        WIDGET_CONTROL, GET_VALUE=read_val, slpb
        selected_path = read_val
        WIDGET_CONTROL, SET_VALUE=paths(selected_path), ptxt
      END
  42: BEGIN
        read_val = ' '
        WIDGET_CONTROL, GET_VALUE=read_val, ptxt
        temp = STRCOMPRESS(read_val(0),/REMOVE_ALL)
        temp = check_for_backslash(temp)
        CASE selected_path OF
          0: path.psc = temp
          1: path.sav = temp
          2: path.gif = temp
        ENDCASE
      END
ENDCASE

END

;--------------------------------------------------------------
; IMAGE DISPLAY CONTROLS
;--------------------------------------------------------------

PRO first_image

COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag

IF NOT (file_flag) THEN BEGIN
  filw = WIDGET_MESSAGE('Please select file first!')
  RETURN
ENDIF

curRec = begRec
make_image,curRec

END

;--------------------------------------------------------------

PRO last_image

COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag

IF NOT (file_flag) THEN BEGIN
  filw = WIDGET_MESSAGE('Please select file first!')
  RETURN
ENDIF

curRec = endRec
make_image,curRec

END

;--------------------------------------------------------------

PRO increment_image

COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum

IF NOT (file_flag) THEN BEGIN
  filw = WIDGET_MESSAGE('Please select file first!')
  RETURN
ENDIF

show_frame = 0
record = curRec
WHILE (record+1 LE endRec) AND (NOT show_frame) DO BEGIN
  record = record + 1
  check_image,record,show_frame
ENDWHILE
IF (record GE endRec) THEN run_flag = 0
IF show_frame THEN BEGIN
  curRec = record
  make_image,record
ENDIF

END

;--------------------------------------------------------------

PRO decrement_image

COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum

IF NOT (file_flag) THEN BEGIN
  filw = WIDGET_MESSAGE('Please select file first!')
  RETURN
ENDIF

show_frame = 0
record = curRec
WHILE (record-1 GE begRec) AND (NOT show_frame) DO BEGIN
  record = record - 1
  check_image,record,show_frame
ENDWHILE
IF (record LE begRec) THEN run_flag = 0
IF show_frame THEN BEGIN
  curRec = record
  make_image,record
ENDIF

END

;--------------------------------------------------------------

PRO forward_event,event

COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum

IF NOT (file_flag) THEN BEGIN
  filw = WIDGET_MESSAGE('Please select file first!')
  RETURN
ENDIF

WIDGET_CONTROL,forw,SET_VALUE='Stop'
WIDGET_CONTROL,forw,EVENT_PRO='stop_event'

run_flag = 1
WHILE (run_flag) DO BEGIN
  IF (curRec+1 LE endRec) THEN increment_image ELSE run_flag = 0
  dest = WIDGET_EVENT(forw,/NOWAIT)
ENDWHILE
run_flag = 0

WIDGET_CONTROL,forw,SET_VALUE=' >> '
WIDGET_CONTROL,forw,EVENT_PRO='forward_event'

END

;--------------------------------------------------------------

PRO reverse_event,event

COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum

IF NOT (file_flag) THEN BEGIN
  filw = WIDGET_MESSAGE('Please select file first!')
  RETURN
ENDIF

WIDGET_CONTROL,revr,SET_VALUE='Stop'
WIDGET_CONTROL,revr,EVENT_PRO='stop_event'

run_flag = 1
WHILE (run_flag) DO BEGIN
  IF (curRec-1 GE begRec) THEN decrement_image ELSE run_flag = 0
  dest = WIDGET_EVENT(revr,/NOWAIT)
ENDWHILE
run_flag = 0

WIDGET_CONTROL,revr,SET_VALUE=' << '
WIDGET_CONTROL,revr,EVENT_PRO='reverse_event'

END

;--------------------------------------------------------------

PRO stop_event,event

COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag

run_flag = 0

END

;--------------------------------------------------------------
; GET PROCEDURES
;--------------------------------------------------------------

PRO get_frm_time,id,record,rate

COMMON STRUCTURES

; GET_FRM_TIME obtains the frame time.
; Frame time is defined as the beginning of the integration period.

lastday = [31,28,31,30,31,30,31,31,30,31,30,31]

epoch = 0.D
CDF_VARGET1,id,'EPOCH',epoch,REC_START=record
CDF_EPOCH,epoch,year,month,day,hour,minute,second,/BREAKDOWN_EPOCH

; offset is the number of seconds before the ATC time
; of the beginning of the integration period.
; offset equals the product of the number of major frames
; before the ATC time and the length of a major frame,
; 9.2 seconds, rounded down.
CASE rate OF
  1: offset = 46     ; 5 x 9.2 s
  2: offset = 55     ; 6 x 9.2 s
  4: offset = 73     ; 8 x 9.2 s
ENDCASE

; calculate year, month, day, hour, minute and second of frame time
sec = second - offset
WHILE (sec LT 0) DO BEGIN
  sec = 60 + sec
  min = minute - 1
  IF (min LT 0) THEN BEGIN
    min = 59
    hou = hour - 1
    IF (hou LT 0) THEN BEGIN
      hou = 23
      daa = day - 1
      IF (daa LT 1) THEN BEGIN
        mon = month - 1
        IF (mon LT 1) THEN BEGIN
          mon = 12
          year = year - 1
        ENDIF
        month = mon
        IF chk_leap_year(year) AND (month EQ 2) THEN daa = 29 $
          ELSE daa = lastday(month-1)
      ENDIF
      day = daa
    ENDIF
    hour = hou
  ENDIF
  minute = min
ENDWHILE
second = sec

; obtain day of year, day of Polar
doy=get_doy(day,month,year)
IF (year GT 1996) THEN add1 = 1 ELSE add1 = 0
dop = CEIL((year - 1996.)*365.25) + doy + add1

; store date and time info in structured format
ft(record).year = year
ft(record).month = month
ft(record).day = day
ft(record).hour = hour
ft(record).minute = minute
ft(record).second = second
ft(record).doy = doy
ft(record).dop = dop

END

;--------------------------------------------------------------

;*******************
;* written by Sid Spencer 19971117
;* this sets up a gain normalization
;* and does the normalizing
;* for the images in studio_new.pro

PRO norm_gain,gain_step,img,img_id,record

  ;* these are the gain and voltage arrays by which
  ;* to make a spline interpolation.

  gain = dblarr(15)
  volts = intarr(15)

  gain_index = gain_step - 1
  gain = [ 1.37e-5, 8.44e-4, 2.75e-3, $
           7.849e-3, 0.026787, 0.048512, $
           0.194856, 0.466903, 1.0, $
           2.548018, 5.509208, 11.51138, $
           54.66714, 218.3204, 977.9447 ]

  volts = [ 856, 1073, 1145, $
            1199, 1262, 1298, $
            1371, 1416, 1452, $
            1506, 1551, 1597, $
            1678, 1777, 1921 ]

  ;* this normalizes the gains to 1678 standard/
	gain = gain / gain(gain_index);

  ;* this initializes a spline fit to the voltage/gain data

  gain2 = SPL_INIT( volts, gain )

  ;* now, the image file is opened and its voltage data is
  ;* retrieved.

  CDF_VARGET1,img_id,'MCP',volts_img,REC_START=record

  ;* this scales the image
  effective_gain = SPL_INTERP( volts, gain, gain2, volts_img )

  img = img / effective_gain

END

;--------------------------------------------------------------

PRO get_dsp_angles,pre=pre

COMMON SFIDS,yydl,mmdl,dddl,ymd
COMMON ORBIT,orb_gci,att_gci,gc_alt
COMMON IDS, img_id, orb_id, att_id, dsp_id, dsp_prev_id
COMMON STRUCTURES
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum

; get the number of records for the primary day
dsp_info = CDF_INQUIRE(dsp_id)
dsp_numrecs = dsp_info.maxrec+1

; Read the dsp angles for the primary day.
tmp = FLTARR(dsp_numrecs)
CDF_VARGET, dsp_id, 'DSP_ANGLE', tmp, REC_COUNT=dsp_numrecs
angle = REFORM( tmp(0,*) )/!DTOR

; Read the UT time for the primary day.
tmp = LONARR(dsp_numrecs)
CDF_VARGET,dsp_id,'Epoch',tmp,REC_COUNT=dsp_numrecs
dsp_epoch = REFORM(tmp(0,*))
dsp_uth = FLTARR(dsp_numrecs)
FOR record=0,dsp_numrecs-1 DO BEGIN
  CDF_EPOCH,dsp_epoch(record),yr,mo,dy,hr,mn,sc,/BREAKDOWN_EPOCH
  dsp_uth(record) = hr + mn/60. + sc/3600.
ENDFOR

; determine if previous day is necessary
IF pre THEN BEGIN
  dsp_info=CDF_INQUIRE(dsp_prev_id)
  dsp_prev_numrecs=dsp_info.maxrec+1

  ; Read in the UT time for the previous day.
  CDF_VARGET,dsp_prev_id,'Epoch',dumy,REC_COUNT=dsp_prev_numrecs
  dsp_prev_uth = FLTARR(dsp_prev_numrecs)
  dsp_prev_epoch = REFORM(dumy(0,*))
  FOR record=0,dsp_prev_numrecs-1 DO BEGIN
    CDF_EPOCH,dsp_prev_epoch(record),yr,mo,dy,hr,mn,sc,/BREAKDOWN_EPOCH
    dsp_prev_uth(record) = hr + mn/60. + sc/3600.
  ENDFOR
  CDF_VARGET, dsp_prev_id, 'DSP_ANGLE', tmp, REC_COUNT=dsp_prev_numrecs
  angle_prev = REFORM( tmp(0,*) )/!DTOR

  ; concatenate the last nlast records to the primary day
  nlast = 10
  i1 = dsp_prev_numrecs - 1
  i0 = i1 - nlast
  angle = [angle_prev(i0:i1),angle]
  dsp_uth = [dsp_prev_uth(i0:i1)-24.,dsp_uth]
ENDIF ELSE dsp_ang = angle

; test dsp angles
; test for sequential ordering; fix if necessary
dsp_ndx = SORT(dsp_uth)
dum = WHERE(dsp_uth NE dsp_uth[dsp_ndx], count)
IF (count GE 1) THEN BEGIN
  display_message,'DSP not sequential..sorting..',wait=0.5
  dsp_uth = dsp_uth[dsp_ndx]
  angle = angle[dsp_ndx]
ENDIF

; test for angles out of bounds
dum = WHERE(ABS(angle) GT 180.,count)
IF (count GE 1) THEN BEGIN
  display_message,'fixed invalid DSP angles...',wait=0.5
  valid = WHERE(ABS(angle) LE 180.)
  dsp_uth = dsp_uth[valid]
  angle = angle[valid]
ENDIF

; hack by Y-K Tung to "fix" bad PO_PA_DEF file on 20021110
; 2/13/03
;
IF (ymd[0] EQ '2002' AND ymd[1] EQ '11' AND ymd[2] EQ '10') THEN BEGIN
  angle[362] = (angle[361] + angle[363])/2.
  angle[1214] = (angle[1213] + angle[1215])/2.
  angle[1342] = (angle[1341] + angle[1343])/2.
  PRINT, 'po_pa_def_20021110_v01.cdf file is fixed by a hack in studio'
endif

; hack by Y-K Tung to "fix" bad PO_PA_DEF file on 20021102
; 2/27/03
;
IF (ymd[0] EQ '2002' AND ymd[1] EQ '11' AND ymd[2] EQ '02') THEN BEGIN
  angle[293] = (angle[292] + angle[294])/2.
  PRINT, 'po_pa_def_20021102_v01.cdf file is fixed by a hack in studio'
ENDIF

interp_angles,dsp_uth,angle,img_numrecs,ii.uthr,img_dsp,ii.rate
ii.dspa = img_dsp

; get the dsp angles from the platform_slews.list file
get_psl_angles,ymd(0)+ymd(1)+ymd(2),img_psl,psl_uth,psl_ang,valid=valid

IF valid THEN BEGIN
  ; check where the definitive dsp angles deviate by delta_dsp
  ; from the master list of instructions
  ; fixes interpol problems due to undersampling
  delta_dsp = 0.2   ; deg
  ndx = WHERE(ABS(img_psl - img_dsp) GT delta_dsp, count)
;  IF (count GT 0) AND (count LT 50) THEN ii[ndx].dspa = img_psl[ndx]
; bump it up to 2000
  IF (count GT 0) AND (count LT 2000) THEN ii[ndx].dspa = img_psl[ndx]
ENDIF ELSE display_message,'No valid PSL file...',wait=0.5

END

;--------------------------------------------------------------

PRO get_psl_angles,yyyymmdd,img_ang,psl_uth,psl_ang,valid=valid

COMMON IDS, img_id,orb_id,att_id,dsp_id,dsp_prev_id
COMMON STRUCTURES
COMMON AUXIL

; get the number of records for the primary day
img_info = CDF_INQUIRE(img_id)
img_numrecs = img_info.maxrec+1
begTime = ii[0].uthr
endTIme = ii[img_numrecs-1].uthr
year = FIX( STRMID( yyyymmdd, 0, 4 ) )
month = FIX( STRMID( yyyymmdd, 4, 2 ) )
day = FIX( STRMID( yyyymmdd, 6, 2 ) )
doy = get_doy( day, month, year )
read_psl,psl_file,year,doy,begTime,endTime,psl_uth,psl_ang,valid=valid

IF valid THEN BEGIN
  ; psl_ang will be returned with the interpolated dsp angles
  img_ang = FLTARR(img_numrecs)

  ; find the DSP record j1 before the beginning of the IP
  psl_numrecs = (SIZE(psl_uth))(1)
  IF (psl_numrecs GT 1) THEN BEGIN
    j1 = FLOOR(interpol(indgen(psl_numrecs),psl_uth,ii.uthr)) 
  ENDIF ELSE BEGIN
    j1 = [0]
    valid = 0
  ENDELSE
  img_ang = psl_ang[j1]
ENDIF

END

;--------------------------------------------------------------

PRO check_image,record,show_frame

COMMON IDS, img_id,orb_id,att_id,dsp_id,dsp_prev_id
COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON STRUCTURES

; determine if the filter(s) is available
filter = ii(record).filt
CASE filseq OF
  0: IF (filter EQ 0) THEN show_frame = 1 ELSE show_frame = 0
  1: IF (filter EQ 1) THEN show_frame = 1 ELSE show_frame = 0
  2: IF (filter EQ 2) THEN show_frame = 1 ELSE show_frame = 0
  3: IF (filter EQ 3) THEN show_frame = 1 ELSE show_frame = 0
  4: IF (filter EQ 4) THEN show_frame = 1 ELSE show_frame = 0
  5: IF (filter EQ 5) THEN show_frame = 1 ELSE show_frame = 0
  6: IF (filter EQ 6) THEN show_frame = 1 ELSE show_frame = 0
; *** include HOME and SHUT images ***
;  7: IF (filter GE 1) AND (filter LT 6) THEN show_frame = 1 $
  7: IF (filter GE 0) AND (filter LE 6) THEN show_frame = 1 $
; ***
       ELSE show_frame = 0
  8: IF (filter EQ 3) OR (filter EQ 4) THEN show_frame = 1 $
       ELSE show_frame = 0
ELSE: show_frame = 0
ENDCASE

; determine if the integration period is available
IF show_frame THEN BEGIN
  rate = ii(record).rate
  nfrm = ii(record).nfrm
  CASE ipseq OF
    0:  show_frame = 1
    1:  IF (rate EQ 4) AND (nfrm EQ 0) THEN show_frame = 1 ELSE show_frame = 0
    2:  IF (rate EQ 2) AND (nfrm EQ 0) THEN show_frame = 1 ELSE show_frame = 0
    3:  IF (rate EQ 1) AND (nfrm EQ 0) THEN show_frame = 1 ELSE show_frame = 0
    4:  IF (nfrm EQ 2) THEN show_frame = 1 ELSE show_frame = 0
    5:  IF (nfrm EQ 1) THEN show_frame = 1 ELSE show_frame = 0
  ELSE: show_frame = 0
  ENDCASE
ENDIF
END

;--------------------------------------------------------------

PRO get_calibrated_image,record,cal_img,img_flag

COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz
COMMON IDS, img_id,orb_id,att_id,dsp_id,dsp_prev_id
COMMON ORBIT,orb_gci,att_gci,gc_alt
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag
COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON IMAGES,raw_img
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON DSPINFO, dspang
COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes
COMMON CALIB,dor_trn,cal_pri,cal_sec
COMMON STRUCTURES
COMMON IMGSTR, uthstr,filstr,ipdstr,dspstr,gaistr,recstr
COMMON PRNTINFO,geob,img_format,pict_index,sav_format
COMMON AUXIL

img_flag = 1

; get housekeeping image variables
tmp_i = ii(record)

filter = tmp_i.filt

gain = tmp_i.gain
IF (gain LT 1) OR (gain GT 15) THEN BEGIN
  gain = ii(record-1).gain
  PRINT,'WARNING: Gain from previous record used: ',gain
ENDIF

system = tmp_i.syst + 1  ;side A is 1, side B is 2
rate = tmp_i.rate
doorpos = tmp_i.door
table_number = tmp_i.tbln
number_of_frames = tmp_i.nfrm

; correct for integration period
; the correction factor is ip_corr = 36.7/ip
CASE table_number OF
  0: BEGIN
       background = bkg_img
       IF (rate GE 1) AND (rate LT 5) THEN ip_corr = 4./rate $
                                      ELSE ip_corr = 1.
     END
;  1: ip_corr = 36.7/(number_of_frames*1.5) 
;  3: ip_corr = 36.7/(number_of_frames*1.5) 
;  5: ip_corr = 36.7/(number_of_frames*1.5) 
  ELSE: BEGIN
          ip_corr = 36.7/(number_of_frames*1.5) 
          CASE number_of_frames OF
            1: background = 28.
            2: background = 55.
            ELSE:
          ENDCASE
        END
ENDCASE

; initialize calibration units and string
CASE cal_unit OF
 0: BEGIN
      units = 1.0
      unitstr = 'photons cm!U-2!N s!U-1!N'
    END
 1: BEGIN
      units = 30.166
      unitstr = '  Rayleighs'
    END
 2: BEGIN
      units = 30.166/110.
      unitstr = 'ergs cm!U-2!N s!U-1!N'
    END
ENDCASE

CASE doorpos OF
  1: door_trans = 1.          ; full extent
  2: door_trans = 1.          ; open
  3: door_trans = dor_trn(filter)
  ELSE: door_trans = 1.
ENDCASE

; obtain absolute calibration factor
IF (filter GE 1.) AND (filter LE 5.) THEN BEGIN
  CASE system OF
    1: BEGIN
         abs = cal_pri(gain-1,filter-1)
         ff_corr = f13_pri
       END
    2: BEGIN
         abs = cal_sec(gain-1,filter-1)
         ff_corr = f13_sec
       END
    ELSE: abs = 1.
  ENDCASE
ENDIF ELSE BEGIN
; *** include HOME and SHUT images ***
  abs = 1.
  CASE system OF
    1: ff_corr = f13_pri
    2: ff_corr = f13_sec
    ELSE: ; do nothing -- hopefully never happens
  ENDCASE
;  display_message,'Filter not available.....',/erase_screen
;  PRINT,'Filter = ',filter
;  img_flag = 0
;  RETURN
; ***
ENDELSE

; get image
extract_image,img_id,record,image
raw_img = image

; clean image
mask = 0.*image
ndx = WHERE(image GT 1., count)
IF (count GT 1) THEN mask[ndx] = 1
bad = 0
IF (menu_value(0)) THEN BEGIN
  image = $
    cleen_image(image,mask,SmScale=5.,THold=[6.,4.],Ped=28.,Bad=Bad)
  print,'Bad pixels: ',Bad
ENDIF

; Ken Clark dewobble algorithm
IF (menu_value(3)) THEN image = dewob_image(image) 

; filter image
smoothing_scale = 3.
IF (menu_value(5)) THEN image = smooth_image(image,smoothing_scale)

; make calibrated (photon flux)
cal_img = ip_corr*abs*ff_corr*(image-background)/door_trans

; Uncomment the following line to enable gain normalization.
; norm_gain,gain,cal_img,img_id,record

END

;--------------------------------------------------------------

PRO make_image,record

COMMON CONSTANTS,earth_radius
COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON PRNTINFO,geob,img_format,pict_index,sav_format
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON STRUCTURES
COMMON ORBIT,orb_gci,att_gci,gc_alt

get_calibrated_image,record,cal_img,img_flag

IF img_flag THEN BEGIN

  IF (scal_value EQ 0) THEN image = cal_img $
                     ELSE image = scale*enhance*cal_img

  ; find string array index for this record
  rx = WHERE(recnum EQ record,crx)
  IF (rx[0] EQ -1) THEN BEGIN
    print,'record not found: ',record
    RETURN
  ENDIF

  header = 'UVI ' $
       + lb(rx).year_str + lb(rx).month_str + lb(rx).day_str + ' ' $
       + lb(rx).hour_str + lb(rx).minute_str + ':' $
       + lb(rx).second_str + ' UT ' $
       + lb(rx).filter_str

  hskpng = lb(rx).ip_str + 'S  ' $
         + lb(rx).dsp_str + '  ' $
         + lb(rx).door_str + '  ' $
         + lb(rx).gain_str + '  ' $
         + STRING(gc_alt(record)/earth_radius,FORMAT='(F3.1)')

  img_map,record,image,cal_img,header,hskpng

ENDIF

END

;--------------------------------------------------------------

PRO rot_con,system,xcon,ycon,roti_val
; Determines the coordinates for a point in the scaled image (228x228)
; given the rotation selected from the menu.

COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz

; corrected 3-21-00 mjb (200->199, 228->227)
scale = 227./199.

CASE system OF
  1: BEGIN
       xcon = scale*(199. - xcon)
       ycon = 227. - ycon
     END
  2:   xcon = scale*(199. - xcon)
ENDCASE

tempx = xcon
tempy = ycon
CASE roti_val OF
  0: ;do nothing
  1: BEGIN
       xcon = nypix - tempy
       ycon = tempx
     END
  2: BEGIN
       xcon = nypix - tempx
       ycon = nypix - tempy
     END
  3: BEGIN
       xcon = tempy
       ycon = nypix - tempx
     END
ENDCASE

END

;--------------------------------------------------------------

PRO get_location,findx,map_type
COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar

  CASE map_type OF
    0: BEGIN
         lat_title = 'Latitude'
         lon_title = 'Longitude'
         stn_title = 'Label'
       END
    1: BEGIN
         lat_title = 'Mlat'
         lon_title = 'MLT'
         stn_title = 'Spacecraft'
       END
    2: BEGIN
         lat_title = 'Right Asc'
         lon_title = 'Declination'
         stn_title = 'Object'
       END
  ENDCASE

  llcw = WIDGET_BASE(COLUMN=1,TITLE='Mark Location')
  latw = CW_FIELD(llcw,TITLE=lat_title,VALUE=markll(0,findx), $
                  /FLOATING,/RETURN_EVENTS)
  lonw = CW_FIELD(llcw,TITLE=lon_title,VALUE=markll(1,findx), $
                  /FLOATING,/RETURN_EVENTS)
  stnw = CW_FIELD(llcw,TITLE=stn_title,VALUE=stncd(findx), $
                  /STRING,/RETURN_EVENTS)
  WIDGET_CONTROL,llcw,/REALIZE
  levent = WIDGET_EVENT(llcw)
  WIDGET_CONTROL,latw,GET_VALUE=lat_arr
  WIDGET_CONTROL,lonw,GET_VALUE=lon_arr
  WIDGET_CONTROL,stnw,GET_VALUE=stn_arr
  WIDGET_CONTROL,llcw,/DESTROY
  markll(0,findx) = lat_arr(0)
  markll(1,findx) = lon_arr(0)
  stncd(findx) = STRTRIM(stn_arr(0)) 

END

;--------------------------------------------------------------

PRO mark_location, x, y, hf, hb, xlab, ylab, label, color=color

COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes

IF ( N_ELEMENTS(color) EQ 0 ) THEN color=0
xvert = [x, x]
;yhorz = [y + 0.2, y + 0.2]
yhorz = [y , y ]

; plot background
IF ct(cur_ct).locat_mark_bg NE -1 THEN BEGIN
  xhorz = [x - hb, x + hb]
  yvert = [y - hb, y + hb]
  oplot,xhorz,yhorz,color=ct(cur_ct).locat_mark_bg,THICK=4
  oplot,xvert,yvert,color=ct(cur_ct).locat_mark_bg,THICK=4
ENDIF

; plot forground
xhorz = [x - hf, x + hf]
yvert = [y - hf, y + hf]
;oplot,xhorz,yhorz,color=ct(cur_ct).locat_mark,THICK=2
;oplot,xvert,yvert,color=ct(cur_ct).locat_mark,THICK=2

colors = [ct[cur_ct].locat_mark,blue,green,red]
oplot,xhorz,yhorz,color=colors[color],THICK=2
oplot,xvert,yvert,color=colors[color],THICK=2

IF (label NE '') THEN $
;  XYOUTS,xlab,ylab,label,COLOR=ct(cur_ct).locat_mark_txt,$
;	  CHARSIZE=1.0,/NORM
  XYOUTS,x,y,' '+label,COLOR=ct(cur_ct).locat_mark_txt,$
	  CHARSIZE=1.0,/DATA
END

;--------------------------------------------------------------

PRO con_plot, clon, clat

COMMON STRUCTURES

tmp1 = [0000, 0521, 2002, 4078, 4109, $
4118, 4129, 4181, 4198, 4207, 4216, 4219, 4233, $
4242, 4300, 4339, 4349, 4360, 4371, 4378, 4384, $
4388, 4398, 4405, 4412, 4416, 4426, 4438, 4450, $
4458, 4465, 4475, 4482, 4534, 4556, 4565, 4680, $
4692, 4700, 4730, 4752, 4815, 4840, 4848, 4855, $
4873, 4899, 4908, 4914, 4923, 4930, 4948, 5031, $
5055, 5061, 5065, 5070, 5074, 5081, 5089, 5098, $
5108, 5120, 5134, 5155, 5196, 5201, 5270, 5277, $
5283, 5291, 5305, 5312, 5319, 5326, 5514, 5521, $
5532, 5538, 5566, 5576, 5585, 5591, 5601, 5606]

tmp2 = [ 5626, 5642, 5659, 5681, 5698, 5778, 5822, 5834, $
5843, 5852, 5860, 5866, 5872, 5925, 5931, 5938, $
5944, 5953, 5970, 5982, 6001, 6042, 6049, 6089, $
6095, 6102, 6109, 6116, 6126, 6133, 6141, 6148, $
6154, 6244, 6275, 6286, 6303, 6321, 6338, 6354, $
6368, 6375, 6394, 6401, 6408, 6418, 6424, 6718, $
6727, 6735, 6759, 6813, 6860, 6865, 6933, 6977]

tmp3 = [ 6984, 7018, 7023, 7029, 7040, 7059, 7065, 7073, $
7085, 7095, 7168, 7248, 7268, 7276, 7293, 7298, $
7304, 7310, 7433, 7480, 7494, 7503, 7521, 7550, $
7594, 7620, 7632, 7641, 7648, 7653, 7658, 7667, $
7674, 7680, 7685, 7701, 7707, 7717, 7726, 7736, $
7745, 7752, 7761, 7770 ]

con_slist = [tmp1, tmp2, tmp3]

tmp1 = [ 0520, 1998, 4075, 4108, 4116, $
4127, 4179, 4196, 4205, 4214, 4218, 4231, 4240, $
4298, 4337, 4348, 4359, 4369, 4376, 4383, 4387, $
4391, 4401, 4408, 4415, 4424, 4436, 4449, 4457, $
4464, 4474, 4480, 4532, 4555, 4564, 4677, 4690, $
4699, 4729, 4751, 4814, 4839, 4847, 4854, 4872, $
4877, 4907, 4913, 4922, 4929, 4947, 4979, 5050, $
5060, 5064, 5069, 5073, 5080, 5088, 5097, 5106, $
5119, 5133, 5154, 5192, 5200, 5269, 5275, 5282, $
5290, 5304, 5308, 5318, 5325, 5513, 5520, 5530, $
5536, 5565, 5575, 5584, 5590, 5600, 5605, 5625 ]

tmp2 = [ 5641, 5658, 5680, 5697, 5777, 5821, 5826, 5841, $
5847, 5859, 5865, 5871, 5919, 5930, 5937, 5942, $
5952, 5969, 5980, 6000, 6041, 6048, 6088, 6094, $
6098, 6107, 6114, 6125, 6132, 6139, 6147, 6153, $
6243, 6274, 6285, 6302, 6320, 6337, 6353, 6367, $
6374, 6380, 6400, 6406, 6417, 6423, 6717, 6725, $
6734, 6757, 6812, 6859, 6864, 6932, 6975, 6983 ]

tmp3 = [ 7017, 7021, 7027, 7038, 7058, 7064, 7071, 7083, $
7090, 7167, 7247, 7267, 7274, 7288, 7296, 7303, $
7309, 7432, 7479, 7493, 7502, 7519, 7549, 7593, $
7615, 7631, 7640, 7644, 7652, 7657, 7665, 7672, $
7678, 7684, 7700, 7705, 7715, 7725, 7735, 7740, $
7751, 7757, 7769, 7784 ]

con_elist = [ tmp1, tmp2, tmp3 ]

n_cons = (size(con_slist))(1)

FOR pos = 0, n_cons - 1 DO $
   OPLOT,clon(con_slist(pos):con_elist(pos)), $
	clat(con_slist(pos):con_elist(pos)), MIN_VALUE=-100, $
        COLOR=mop.concol(mop.concolndx)

END

;--------------------------------------------------------------

PRO grid_plot,lat,lon,xpimg,ypimg,sslat

COMMON STRUCTURES

t_lat = CONGRID(lat, xpimg, ypimg, /INTERP)
t_lon = CONGRID(lon, xpimg, ypimg)

nlat = 51
; find the nearest whole number of latdels to the sslat
midl = FIX( sslat - ( sslat MOD mop.latdel ) )
; generate nlat increments centered about 0 of size latdel
incr = mop.latdel*( INDGEN(nlat) - (nlat - 1)/2 )
temp = midl + incr
indx = WHERE(temp GT -90 AND temp LT 90, count)
IF (count GT 0) THEN lat_lvls = temp(indx)

CONTOUR, t_lat, LEVELS=lat_lvls,/OVERPLOT,COLOR=mop.grdcol(mop.grdcolndx)

nlon = FIX( 360. / mop.londel )
t_lon = TAN( t_lon * nlon *!DTOR / 2. )

CONTOUR, t_lon, LEVELS=0,/OVERPLOT,$
  COLOR=mop.grdcol(mop.grdcolndx),$
  THICK=1., MAX_VALUE=2., MIN_VALUE=-2.

END

;--------------------------------------------------------------
; Get the appropriate weightings for where to draw the grid
; labels.

PRO get_grd_wght, lat, lon, x, y, grad

; Should probably do some transforms or weightings of some
; form to get a more accurate answer for what we want.

theta = (90-lat)*!DTOR
phi = lon*!DTOR
dtheta_x = theta( x, y ) - theta( x + 1, y )
dtheta_y = theta( x, y ) - theta( x, y + 1 )
dphi_x = sin( theta( x, y ) ) * (phi( x, y ) - phi( x + 1, y ))
dphi_y = sin( theta( x, y ) ) * (phi( x, y ) - phi( x, y + 1 ))
grad = dtheta_x*dtheta_x + dtheta_y*dtheta_y $
	+ dphi_x*dphi_x + dphi_y*dphi_y

;dlat_x = lat( x, y ) - lat( x + 1, y )
;dlat_y = lat( x, y ) - lat( x, y + 1 )
;
;dlon_x = lon( x, y ) - lon( x + 1, y )
;dlon_y = lon( x, y ) - lon( x, y + 1 )
;
;grad = dlat_x*dlat_x + dlat_y*dlat_y $
;	+ dlon_x*dlon_x + dlon_y*dlon_y

END

;--------------------------------------------------------------

PRO calc_drawn_grd_lines, lat, lon, lat_lst, lon_lst, count=count

COMMON STRUCTURES

lat_pos=WHERE( (lat GE -90) AND (lat LE 90), count )

IF count LE 0L THEN RETURN

; Find the range of latitudes.
lat_max = MAX( lat( lat_pos ), MIN=lat_min )
lon_max = MAX( lon( lat_pos ), MIN=lon_min )
mid_lat = (lat_max + lat_min) / 2.
mid_lon = (lon_max + lon_min) / 2.

lon_sep = 360. / FIX( 360. / mop.londel )
lat_sep = 180. / FIX( 180. / mop.latdel )

n_lat_lines = FIX( lat_max - lat_min ) / lat_sep + 2
n_lon_lines = FIX( lon_max - lon_min ) / lon_sep + 2
cur_lat = FIX(lat_min / lat_sep) * lat_sep
IF (cur_lat LT 0) AND (cur_lat MOD lat_sep) THEN $
	cur_lat = cur_lat - lat_sep

cur_lon = FIX(lon_min / lon_sep) * lon_sep

lat_lst = FINDGEN( n_lat_lines ) * lat_sep + cur_lat
tmp = WHERE( lat_lst GE 90., count )
IF count GT 0 THEN BEGIN
   n_lat_lines = n_lat_lines - count
   lat_lst = lat_lst( 0:n_lat_lines - count )
ENDIF

lon_lst = FINDGEN( n_lon_lines ) * lon_sep + cur_lon

IF n_lat_lines LE 2 THEN BEGIN
  n_lat_lines = 2
  lat_lst( 0 ) = mid_lat - lat_sep
  lat_lst( 1 ) = mid_lat + lat_sep
ENDIF

IF n_lat_lines EQ 3 THEN BEGIN
  lat_lst( 0 ) = lat_min - .02
  lat_lst( 2 ) = lat_max + .02
ENDIF 

IF n_lon_lines LE 2 THEN BEGIN
  n_lon_lines
  lon_lst( 0 ) = mid_lon - lon_sep
  lon_lst( 1 ) = mid_lon + lon_sep
ENDIF

IF n_lon_lines EQ 3 THEN BEGIN
  lat_lst( 0 ) = lat_min - .02
  lat_lst( 2 ) = lat_max + .02
ENDIF

END

;--------------------------------------------------------------
; This routine takes in two lists, one for latitude and one for
; longitude.  It then computes points at the in_lst1 and in 
; between the points of in_lst2.  It also produces a list of
; labels from in_lst1.  Count returns the total number of points
; created.

PRO calc_labels, in_lst1, in_lst2, out_lst1, out_lst2, lab_lst, count=count

in_lines1 = (SIZE( in_lst1 ))(1)
in_lines2 = (SIZE( in_lst2 ))(1)

tot_lines = in_lines1 * in_lines2 * 2

count = tot_lines

IF tot_lines LE 0 THEN RETURN

out_lst1 = DBLARR( tot_lines )
out_lst2 = DBLARR( tot_lines )
lab_lst = STRARR( tot_lines )

indx = 0
pos2 = 0
FOR pos1 = 0, in_lines1 - 1 DO BEGIN
  FOR pos2 = 0, (in_lines2 - 2) DO BEGIN
    out_lst1( indx ) = in_lst1( pos1 )
    out_lst2( indx ) = (in_lst2( pos2 ) + in_lst2( pos2 + 1 )) / 2.
    lab_lst( indx ) = STRING(FIX(in_lst1( pos1 )))
    indx = indx + 1
  ENDFOR
ENDFOR

out_lst1 = out_lst1( 0:indx - 1 )
out_lst2 = out_lst2( 0:indx - 1 )
lab_lst = lab_lst( 0:indx - 1 )

count = indx

END

;--------------------------------------------------------------
; This creates a list of upto three valid points that fit on $
; the image, and also weeds out duplicates by deciding where $
; the curviture of the earth changes the least.

PRO get_valid_xy, xdev, ydev, adev, xpimg, ypimg, lat, lon, $
	lat_list, lon_list, lab_list, x, y, lab, count=count

; Orriginally xdev & ydev were supposed to be LT 228., but do to grad
; routine, I changed it to be 227.
valid = WHERE( (adev GT (!DPI * 0.5D)) AND $
	(xdev GT 0.) AND (ydev GT 0.) AND $
	(xdev LT (xpimg - 1)) AND (ydev LT (ypimg-1)) AND $ 
	(lon_list LT 360.) AND (lon_list GE 0), count )

IF count GT 0 THEN BEGIN
  x = xdev( valid )
  y = ydev( valid )
  lab = lab_list( valid )

  ; Out of all the labels on the screen, pick out the ones where the lat
  ; and lon are changing the least.
  get_grd_wght, lat, lon, x, y, grad

  w_test = DOUBLE( lab ) + 1.D / (1.01D + grad)
  w_test = w_test( SORT( w_test ) )

  v2 = UNIQ( LONG( w_test ) )
  x = x( v2 )
  y = y( v2 )
  lab = lab( v2 )

  tmp = SIZE(x)
  IF tmp(0) NE 0 THEN $
    count = tmp(1) $
  ELSE $
    count = 1

  IF count GT 3 THEN BEGIN
    ; If the discontinuity is around then spread the labels around a
    ; bit differently
    IF (FIX( lab(0) ) LT 45) AND (FIX( lab(count - 1) ) GT 300) THEN $
      items = [ 0, count / 3, 2*count / 3 ] $
    ELSE $
      items = [ 0, count / 2, count - 1 ]
    x = x(items)
    y = y(items)
    lab = lab(items)
  ENDIF
ENDIF

END

;--------------------------------------------------------------
; A routine to draw the labels on the geographic grid with the
; latitude and longitude.

PRO label_grid, lat, lon, xpimg, ypimg, rotm, emis_hgt, $
	xax, yax, zax, o_gci, time, system

COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON STRUCTURES

; Set how much to offset the text.
x0 = 0
y0 = 0

calc_drawn_grd_lines, lat, lon, full_lat_lst, full_lon_lst, count=count
IF count LE 0 THEN RETURN

calc_labels, full_lat_lst, full_lon_lst, lat_list, lon_list, $
	lab_list, count=count

IF count LE 0 THEN RETURN

lltopix_arr, lat_list, lon_list, emis_hgt, $
	xax, yax, zax, o_gci, time, system, $
	ydev, xdev, adev, rotm
rot_con, system, xdev, ydev, roti_val

get_valid_xy, xdev, ydev, adev, xpimg, ypimg, lat, lon, $
	lat_list, lon_list, lab_list, x, y, lab, count=count

IF count GT 0 THEN $
  xyouts, x - x0, y - y0, STRCOMPRESS( lab ), $
	COLOR=mop.grdcol(mop.grdcolndx), /DATA

calc_labels, full_lon_lst, full_lat_lst, lon_list, lat_list, $
	lab_list, count=count
IF count LE 0 THEN RETURN

lltopix_arr, lat_list, lon_list, emis_hgt, $
	xax, yax, zax, o_gci, time, system, $
	ydev, xdev, adev, rotm
rot_con, system, xdev, ydev, roti_val

get_valid_xy, xdev, ydev, adev, xpimg, ypimg, lat, lon, $
	lat_list, lon_list, lab_list, x, y, lab, count=count
IF count GT 0 THEN $
  xyouts, x - x0, y - y0, STRCOMPRESS( lab ), $
	COLOR=mop.grdcol(mop.grdcolndx), /DATA

END

;--------------------------------------------------------------
; Finds all grid lines in the image
; Called by grid_lab

FUNCTION find_lines,min,max,del,count

min_lin = min - (min mod del)
max_lin = max - (max mod del)
num_lin = (max_lin - min_lin)/del
tmp_lin = min_lin + INDGEN(num_lin+1)*del
ndx = WHERE(tmp_lin GE min and tmp_lin LE max, count)
IF (count GT 0) THEN lines = tmp_lin(ndx) ELSE lines = [0]

RETURN, lines

END

;--------------------------------------------------------------
; A routine to draw the labels on the geographic grid with the
; latitude and longitude.

PRO grid_lab, lat, lon, xpimg, ypimg, rotm, emis_hgt, $
	xax, yax, zax, o_gci, time, system

COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON STRUCTURES

earth = WHERE( (lat GE -90) AND (lat LE  90), count )

IF count LE 0L THEN RETURN

; find the gridlines in the image
lat_max = MAX( lat(earth), MIN=lat_min )
lon_max = MAX( lon(earth), MIN=lon_min )
lat_lin = find_lines(lat_min,lat_max,mop.latdel,lat_num)
lon_lin = find_lines(lon_min,lon_max,mop.londel,lon_num)

; largest |lat|
tlat = lat_lin(lat_num-1)
td = 0.2
tl0 = tlat - td
tl1 = tlat + td
ndx = WHERE( (lat(earth) GT tl0) AND (lat(earth) LE tl1), count )
lat_max1 = MAX( lat(earth), MIN=lat_min1 )
lat_lin1 = find_lines(lat_min1,lat_max1,mop.latdel,lat_num1)

nlat = lat_num < 4
nlon = lon_num < 4

END

;--------------------------------------------------------------

PRO draw_geo,image,header,hskpng,record,rotm,a_gci,o_gci,l0,$
	lat,lon,xcon,ycon,min,max,sslat,sslon,pict=pict,IS_PS=is_ps,$
	USE_LAST_FOOTPOINT=use_last_footpoint

COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz
COMMON WINDINFO,main_windex,xmsg,ymsg,imsg,orbit_windex,model_windex
COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes
COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON STRUCTURES
COMMON AUXIL
COMMON ORBIT,orb_gci,att_gci,gc_alt
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum

system = ii(record).syst + 1

img = image
xpimg = nypix
ypimg = nypix

xax = unit_vec(l0)
yax = unit_vec(CROSSP(a_gci,l0))
zax = unit_vec(CROSSP(xax,yax))

pos_w = FLTARR(4)
pos_i = FLTARR(4)
pos_h = FLTARR(4)
pos_c = FLTARR(4)

IF KEYWORD_SET(IS_PS) THEN BEGIN
  im = 0.75
  hd = 0.06
  cb = 0.25
  bd = 0.04*im
  IF (show_cbar) THEN u = im + cb $
    ELSE u = im
  v = im + hd
  ; window background
  pos_w = [0,0,u,v]
  ; image
  pos_i = [bd,bd,im-bd,im-bd]
  ; header
  hx0 = bd
  hy0 = im
  ; color bar
  r0 = im + 0.25*cb
  s0 = bd
  r1 = r0 + 0.2*cb
  s1 = im - bd
  pos_c = [r0,s0,r1,s1]
  hcharsiz = ps.header
ENDIF ELSE BEGIN
  WSET,main_windex
  border = 10
  xwinp = xwin
  ywinp = ywin
  x_img_org = border
  y_img_org = border
  ; window coordinates
  pos_w = [ 0.0, 0.0, 1.0, 1.0 ]
  ; image coordinates
  pos_i( 0 ) = (1.0 * x_img_org) / xwinp
  pos_i( 1 ) = (1.0 * y_img_org) / ywinp
  pos_i( 2 ) = (1.0 * x_img_org + xpimg ) / xwinp
  pos_i( 3 ) = (1.0 * y_img_org + ypimg ) / ywinp
  ; header
  hx0 = 1.0*border / xwinp
  hy0 = (1.5 * border + ypimg) / ywinp
  ; color bar
  r0 = x_img_org + xpimg + border + 18
  s0 = y_img_org
  r1 = r0 + 10
  s1 = s0 + ypimg
  pos_c = [r0,s0,r1,s1]
  hcharsiz = charsiz
ENDELSE

; plot background
bkgd = REPLICATE(ct(cur_ct).bkgrnd_clr,3,3)
ERASE
TVimage, bkgd, POSITION=pos_w, NCOLORS=top_color+1

; plot image
img = ROTATE(img,roti_val)
;IF menu_value(5) THEN img = SMOOTH(img,3)
TVimage, img>0<white, POSITION=pos_i, NCOLORS=top_color+1

; establish plotwindow for image
xrange = [0,xpimg]
yrange = [0,ypimg]
PLOT,[0,0],[0.0],/NODATA,XRANGE=xrange,YRANGE=yrange, $
  POSITION=pos_i,/NOERASE,/NORM,XSTYLE=13,YSTYLE=13

; draw noon meridian
;nmlat = -90. + FINDGEN(181)
;nmlon = sslon*REPLICATE(1.0,181)
;lltopix_arr,geoglat,geoglon,emis_hgt, $
;         xax,yax,zax,o_gci,time,system,$
;         ydev,xdev,adev,rotm
;adx = WHERE(adev GT 0.5*!PI,npts)
;IF (npts GT 0) THEN BEGIN
;  xln = xdev(adx)
;  yln = ydev(adx)
;  rot_con,system,xln,yln,roti_val
;  OPLOT,xln,yln,COLOR=blue
;ENDIF

; overplot FAST if requested
; if menu_value[7] then begin
;     overplot_fast_orbit_geo, rotm, a_gci, l0, o_gci, record
; endif

; draw continents
IF mop.putcon THEN con_plot, xcon, ycon

; draw latitude and longitude lines
IF mop.putgrd THEN grid_plot,lat,lon,xpimg,ypimg,sslat

; label gridlines 
IF mop.putlab THEN label_grid, lat, lon, xpimg, ypimg, rotm, $
	emis_hgt, xax, yax, zax, o_gci, time, system
;IF mop.putlab THEN grid_lab, lat, lon, xpimg, ypimg, rotm, $
;	emis_hgt, xax, yax, zax, o_gci, time, system

; add location mark
IF (menu_value(6)) THEN BEGIN
  FOR i=0,mark_val DO BEGIN
    IF NOT KEYWORD_SET( USE_LAST_FOOTPOINT ) THEN get_location,i,0
    l_lat = markll(0,i)

    IF (markll(1,i) LE 180.) THEN l_lon = markll(1,i) $
      ELSE l_lon = markll(1,i) - 360.

    lltopix_arr,l_lat,l_lon,emis_hgt, $
         xax,yax,zax,o_gci,time,system,$
         ydev,xdev,adev,rotm

    rot_con,system,xdev,ydev,roti_val

    hf = 6  ; length of foreground cursor lines
    hb = 7  ; length of background cursor lines

;    x_lab = (xdev + 6) / xwinp  ; x label position
;    y_lab = (ydev - 3) / ywinp  ; y label position

    mark_location, xdev, ydev, hf, hb, x_lab, y_lab, stncd(i)
  ENDFOR
END

IF mop.stars[0] THEN BEGIN
;  print, mop.nstars
;  help, mop, /st
  FOR i=0,mop.nstars-1 DO BEGIN
;    print, mop.hd[i], mop.xl[i], mop.yl[i]
    mark_location, mop.xl[i], mop.yl[i], 6, 7, $
    mop.xl[i]+6, mop.yl[i]+6,mop.hd[i], $
       color=mop.cl[i]
  ENDFOR
ENDIF

; produce color bar
IF (show_cbar) THEN BEGIN
  windex = !D.WINDOW
  color_bar,windex,pos_c,min,max,IS_PS=IS_PS
ENDIF

XYOUTS,hx0,hy0,header,CHARSIZE=hcharsiz,/NORMAL, $
       COLOR=ct( cur_ct ).header

END

;-------------------------------------------------------------

PRO geo2mlt,image,lat_mag,mlt,mlt_img,alat,amlt,norm_rsat, $
      record

COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz
COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON STRUCTURES

; INPUTS:
; image     calibrated image in photon flux units (200x228)
; lat_mag   magnetic latitude (200x228)
; mlt       mlt hour angle (200x228)
; latmin    minimum latitude (scalar)

; OUTPUTS   [ ncell = 4*(90 - latmin) ]
; mlt_img   transformed image (ncellxncell)
; alat      magnetic latitude file (ncellxncell)
; amlt      mlt hour angle file (ncellxncell)

ncell = FIX(4.*(90. - mop.latmin))
lat_lim = (90. - mop.latmin)
del = 2.*lat_lim/FLOAT(ncell)

; transform from lat/lon to cartesian coordinates
xpr = lat_lim + (90. - ABS(lat_mag))*sin(15.D * mlt * !DTOR)
ypr = lat_lim - (90. - ABS(lat_mag))*cos(15.D * mlt * !DTOR)
m = ROUND(xpr/del) < (ncell - 1)
n = ROUND(ypr/del) < (ncell - 1)

; fill bins and keep record of the number of items
mlt_img = REPLICATE(0.,ncell,ncell)
mlt_cnt = REPLICATE(0.,ncell,ncell)

; New much quicker code.  Speeds up processing a lot, especially if
; not all of the image will fall into the mlt dial.
tmp_loc = WHERE( ABS( lat_mag ) GT mop.latmin, tmp_cnt )
IF tmp_cnt LT 1 THEN RETURN
tmp_loc_m = m( tmp_loc )
tmp_loc_n = n( tmp_loc )
FOR i=0L, tmp_cnt-1 DO BEGIN
    m2 = tmp_loc_m( i )
    n2 = tmp_loc_n( i )
    mlt_img( m2, n2 ) = mlt_img( m2, n2 ) + image( tmp_loc(i) )
    mlt_cnt( m2, n2 ) = mlt_cnt( m2, n2 ) + 1
ENDFOR

; average all bins  (mjb: fixed 3-20-00)
; make sure we do not divide by 0
mlt_img = ( mlt_img/(mlt_cnt > 1.) ) > 0.  ; average and enforce positivity

; create mlt and lat arrays for lower end point
x = (del*FINDGEN(ncell) - lat_lim) # REPLICATE(1.,ncell)
y = TRANSPOSE(x)
alat = 90. - SQRT(x*x + y*y)
amlt = (ATAN(-x,y)/!DTOR + 180.)/15.

; fill in undersampled bins within the MLT dial
; this wastes memory but works faster
b = 1
tmp_img = REPLICATE(0.,ncell,ncell)
xpd_img = REPLICATE(0.,ncell+2*b,ncell+2*b)
xpd_img[b,b] = mlt_img
xpd_cnt = REPLICATE(0.,ncell+2*b,ncell+2*b)
xpd_cnt[b,b] = mlt_cnt

usndx = WHERE(mlt_cnt EQ 0. AND alat GE mop.latmin,uscount)
IF (uscount GT 0) THEN BEGIN
  m_tmp = ( usndx MOD ncell ) + b
  n_tmp = FLOOR( 1.*usndx / ncell ) + b
  FOR i = 0L, uscount-1 DO BEGIN
    m = m_tmp(i)
    n = n_tmp(i)
    subimg = xpd_img(m-b:m+b,n-b:n+b)
    good_index = WHERE(xpd_cnt(m-b:m+b,n-b:n+b) GT 0,ngdndx) 
    IF (ngdndx GT 0) THEN $
      tmp_img(m-b,n-b) = TOTAL(subimg(good_index))/ngdndx
  ENDFOR
ENDIF
mlt_img = mlt_img + tmp_img

UNDEFINE,tmp_img,xpd_img,xpd_cnt,m_tmp,n_tmp,m,n,subimg,good_index

END

;-------------------------------------------------------------

PRO binmlt,cal_img,mlt,lat_mag,nmlt,nlat,mlt_bin

COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz
COMMON STRUCTURES

; specify resolution
latres = 0.5    ; degrees
mltres = 0.25   ; hours
latmin = mop.latmin
latmax = 90.

nmlt = FIX(24.0/mltres)
nlat = FIX((latmax - latmin)/latres)
mlt_bin = FLTARR(nmlt,nlat)
mlt_cnt = FLTARR(nmlt,nlat)

FOR i=0,nxpix-1 DO BEGIN
  FOR j=0,nypix-1 DO BEGIN
    IF (lat_mag(i,j) GE latmin) THEN BEGIN
      m = FIX(mlt(i,j)/mltres)
      n = FIX((lat_mag(i,j)-latmin)/latres)
      IF (m GE 0 AND m LT nmlt AND n GE 0 AND n LT nlat) THEN BEGIN
        mlt_bin(m,n) = mlt_bin(m,n) + cal_img(i,j)
        mlt_cnt(m,n) = mlt_cnt(m,n) + 1.
      ENDIF
    ENDIF
  ENDFOR
ENDFOR

mlt_cnt = mlt_cnt > 1.
mlt_bin = mlt_bin/mlt_cnt

UNDEFINE, mlt_cnt,m,n
END

;-------------------------------------------------------------

PRO get_flux,image,lat_mag,mlt,flx_bin,flx_err,flatmin,flatmax,mlt0,mlt1

COMMON IMAGES,raw_img
COMMON AUXIL

; create inverse fov mask; valid image = 0., outside fov = 1.
fov = REPLICATE(1.,200,228)
fov(WHERE(bkg_img GT 1.)) = 0.

;flatmin = 58.  ;60.  ;60.
;flatmax = 74.  ;80.  ;74.
;mlt0 = 16.
;mlt1 = 6.

if (mlt0 GT mlt1) then nmlt = mlt1+24-mlt0 else nmlt = mlt1-mlt0
flx_bin = FLTARR(nmlt)
flx_err = FLTARR(nmlt)

FOR i=0,nmlt-1 DO BEGIN
  mltbin = (mlt0 + i) MOD 24.
  ndx = WHERE( (lat_mag GE flatmin) AND (lat_mag LT flatmax) AND $
               (FLOOR(mlt) EQ mltbin) , count)
  IF (count GT 0.) THEN BEGIN
    flx_bin(i) = TOTAL(image(ndx))/count ; average flux
    flx_err(i) = TOTAL(fov(ndx))/count   ; pixel fraction outside fov
  ENDIF
ENDFOR

END

;-------------------------------------------------------------

PRO  img_bound,lat_mag,mlt,xfov,yfov

COMMON IMAGES,raw_img
COMMON AUXIL
COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz
COMMON STRUCTURES

k = 0
blat = FLTARR(1000)
bmlt = FLTARR(1000)
xbnd = FLTARR(1000)
ybnd = FLTARR(1000)

; find bottom edge
i = 0
WHILE (raw_img(i,0) LT 1. AND i LT nxpix/2) DO i = i + 1
WHILE (raw_img(i,0) GT 1. AND i LT nxpix) DO BEGIN
  xbnd(k) = i
  ybnd(k) = 0
  blat(k) = lat_mag(i,0)
  bmlt(k) = mlt(i,0)
  i = i + 1
  k = k + 1
ENDWHILE

; find right edge
FOR j=2,nypix-3 DO BEGIN
  i = nxpix - 1
  WHILE (raw_img(i,j) LT 1. AND i GT nxpix/2) DO i = i - 1
  xbnd(k) = i
  ybnd(k) = j
  blat(k) = lat_mag(i,j)
  bmlt(k) = mlt(i,j)
  k = k + 1
ENDFOR
  
; find top edge
i = nxpix - 1
WHILE (raw_img(i,nypix-1) LT 1. AND i GT nxpix/2) DO i = i - 1
WHILE (raw_img(i,nypix-1) GT 1. AND i GT 0) DO BEGIN
  xbnd(k) = i
  ybnd(k) = nypix-1
  blat(k) = lat_mag(i,nypix-1)
  bmlt(k) = mlt(i,nypix-1)
  i = i - 1
  k = k + 1
ENDWHILE

; find left edge
FOR j=nypix-2,1,-1 DO BEGIN
  i = 0
  WHILE (raw_img(i,j) LT 1. AND i LT nxpix/2) DO i = i + 1
  xbnd(k) = i
  ybnd(k) = j
  blat(k) = lat_mag(i,j)
  bmlt(k) = mlt(i,j)
  k = k + 1
ENDFOR

bndx = WHERE(blat GE mop.latmin,count)
IF (count GT 0) THEN BEGIN
  blat = blat(bndx)
  bmlt = bmlt(bndx)
  xfov =  (90. - blat)*sin(15.D * bmlt * !DTOR)
  yfov = -(90. - blat)*cos(15.D * bmlt * !DTOR)
ENDIF

END

;-------------------------------------------------------------

PRO draw_mlt_grid,pos_n,lat_lim,IS_PS=IS_PS

COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes
COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz
COMMON STRUCTURES
COMMON IMGINFO

; parameters
txt_clr = ct( cur_ct ).txt_clr
lin_clr = ct( cur_ct ).mlt_line
lin_sty = 0

IF KEYWORD_SET(IS_PS) THEN chr_siz = ps.glabel $
  ELSE chr_siz = charsiz

; plot latitude circles
npts = 500
a = FINDGEN(npts)*(!PI*2.05/FLOAT(npts))
cx = 10.*cos(a)
cy = 10.*sin(a)
PLOT,cx,cy,/NOERASE,/NODATA,COLOR=lin_clr,linestyle=lin_sty, $
   position=pos_n, /NORMAL, $
   xstyle=1+4,ystyle=1+4, $
   xrange=[-lat_lim,lat_lim], $
   yrange=[-lat_lim,lat_lim]
ncirc = ROUND(.1*lat_lim)
FOR i=0,ncirc-1 DO BEGIN
  scl = i + 1.0
  IF (i EQ ncirc-1) THEN BEGIN 
    xcir = 0.98*scl*cx
    ycir = 0.98*scl*cy
    oplot,xcir,ycir,COLOR=ct(cur_ct).mlt_out_line,$
	linestyle=lin_sty
  ENDIF ELSE oplot,scl*cx,scl*cy,COLOR=lin_clr,linestyle=lin_sty
ENDFOR

; plot longitude lines
lx1 = -lat_lim + 2.*lat_lim*FINDGEN(npts)/(npts-1.)
ly1 = 0.*lx1
ly2 = -lat_lim + 2.*lat_lim*FINDGEN(npts)/(npts-1.)
lx2 = 0.*ly2
lx3 = SQRT(0.5)*lx1
ly3 = lx3
lx4 = lx3
ly4 = -ly3
oplot,lx1,ly1,COLOR=lin_clr,linestyle=lin_sty
oplot,lx2,ly2,COLOR=lin_clr,linestyle=lin_sty
oplot,lx3,ly3,COLOR=lin_clr,linestyle=lin_sty
oplot,lx4,ly4,COLOR=lin_clr,linestyle=lin_sty

; label MLT and MLat
xh = [1,lat_lim-3,1,-lat_lim+1]
yh = [-lat_lim+1,1,lat_lim-4,1]
s2 = SQRT(50.)
xl = s2*(1.+FINDGEN(3))+2
yl = s2*(1.+FINDGEN(3))-1
XYOUTS,xh(0),yh(0), '0',COLOR=txt_clr,CHARSIZE=chr_siz,/DATA
XYOUTS,xh(1),yh(1), '6',COLOR=txt_clr,CHARSIZE=chr_siz,/DATA
XYOUTS,xh(2),yh(2),'12',COLOR=txt_clr,CHARSIZE=chr_siz,/DATA
XYOUTS,xh(3),yh(3),'18',COLOR=txt_clr,CHARSIZE=chr_siz,/DATA
XYOUTS,xl(0),yl(0),'80',COLOR=txt_clr,CHARSIZE=chr_siz,/DATA
XYOUTS,xl(1),yl(1),'70',COLOR=txt_clr,CHARSIZE=chr_siz,/DATA
XYOUTS,xl(2),yl(2),'60',COLOR=txt_clr,CHARSIZE=chr_siz,/DATA

; if menu_value[7] then begin
;     overplot_fast_orbit_mlt
; endif

END

;--------------------------------------------------------------

PRO draw_mlt,mlt_img,header,hskpng,record,min,max,xfov,yfov, $
	    IS_PS=is_ps,USE_LAST_FOOTPOINT=use_last_footpoint

COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes
COMMON WINDINFO,main_windex,xmsg,ymsg,imsg,orbit_windex,model_windex
COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz
COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON STRUCTURES

; parameters
lat_lim = 90. - mop.latmin
img_siz = 242.
xwinp = xwin
ywinp = ywin

pos_w = FLTARR(4)
pos_i = FLTARR(4)
pos_h = FLTARR(4)
pos_c = FLTARR(4)

IF KEYWORD_SET(IS_PS) THEN BEGIN
  im = 0.75
  hd = 0.06
  cb = 0.25
  bd = 0.04*im
  IF (show_cbar) THEN u = im + cb $
    ELSE u = im
  v = im + hd
  ; window background
  pos_w = [0,0,u,v]
  ; image
  pos_i = [bd,bd,im-bd,im-bd]
  ; header
  x0 = bd
  y0 = im + 0.2*bd
  ; color bar
  r0 = im + 0.25*cb
  s0 = bd
  r1 = r0 + 0.2*cb
  s1 = im - bd
  pos_c = [r0,s0,r1,s1]
  hcharsiz = ps.header
ENDIF ELSE BEGIN
  WSET,main_windex
  ; window background
  u = xwin
  v = ywin
  pos_w = [ 0.0, 0.0, 1.0, 1.0 ]
  ; image
  pos_i( 0 ) = 1.0 * border / xwinp
  pos_i( 1 ) = 1.0 * border / ywinp
  pos_i( 2 ) = (1.0 * border + img_siz ) / xwinp
  pos_i( 3 ) = (1.0 * border + img_siz ) / ywinp
  ; header
  x0=1.0*border / xwinp
  y0=(1.7 * border + img_siz) / ywinp
  ; color bar
  r0 = 3*border + img_siz
  s0 = border
  r1 = r0 + 10
  s1 = s0 + img_siz
  pos_c = [r0,s0,r1,s1]
  hcharsiz = charsiz
ENDELSE

; put background on screen
bkgd = REPLICATE(ct( cur_ct ).bkgrnd_clr,3,3)
ERASE
TVimage, bkgd, POSITION=pos_w, NCOLORS=top_color+1

TVimage, mlt_img>0, POSITION = pos_i

IF mop.fov THEN BEGIN
  ; draw edge of FOV
  r = 0.3
  t = 2.*!PI*FINDGEN(40)/(37.)
  USERSYM,r*sin(t),r*cos(t),/FILL
  PLOT,xfov,yfov,PSYM=8,/NOERASE, $
    POSITION=pos_i, /NORMAL, $
    COLOR=ct(cur_ct).fov_edge, $
    XSTYLE=1+4,ystyle=1+4, $
    XRANGE=[-lat_lim,lat_lim], $
    YRANGE=[-lat_lim,lat_lim]
ENDIF

draw_mlt_grid,pos_i,lat_lim,IS_PS=IS_PS

XYOUTS,x0,y0,header,CHARSIZE=hcharsiz,/NORMAL, COLOR=ct( cur_ct ).header

; add location mark
IF (menu_value(6)) THEN BEGIN
  FOR i=0,mark_val DO BEGIN
    IF NOT KEYWORD_SET( use_last_footpoint ) THEN get_location,i,1
    mlat = markll(0,i)
    mlt = markll(1,i)
    radius = 90. - mlat
    theta = (mlt*15. - 90.)*!DTOR
    xpos = radius*cos(theta)
    ypos = radius*sin(theta)
    mark_location, xpos, ypos, 1.5, 1.8, xpos + 2, ypos - 1, stncd(i)
  ENDFOR
ENDIF

IF (show_cbar) THEN BEGIN
  windex = !D.WINDOW
  color_bar,windex,pos_c,min,max,IS_PS=IS_PS
ENDIF

END

;--------------------------------------------------------------

PRO scale_img, min, max, units, img

COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes
COMMON SCALE, min_log_scl,max_log_scl,amp,phi

; calibration unit scaling
units = [1., 30.166, 30.166/110.]

; scale image for display and initialize color bar
IF (scal_value EQ 0) THEN BEGIN
  ; logarithmic scaling
  min = min_log_scl
  max = max_log_scl
  pre_scl = 1./min                         ; Fit bottom of color table.
  post_scl = top_color/ALOG(max*pre_scl)   ; Fit top of color table.
  img = ALOG(pre_scl*units(cal_unit)*img > 1.)*post_scl

ENDIF ELSE BEGIN
  ; linear scaling
  min = 0.
  CASE cal_unit OF
    0: max = white/(enhance*scale)
    1: max = white*30.166/(enhance*scale)
    2: max = white*(30.166/110.)/(enhance*scale)
  ENDCASE
ENDELSE

END

;--------------------------------------------------------------

PRO final_prep_geo, system, img, l0, a_gci, o_gci, lat, lon, $
	xcon, ycon, rotm

COMMON AUXIL
COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON STRUCTURES

  ; correct image for system orientation
  CASE system OF
    1: img = ROTATE(img,2)
    2: img = REVERSE(img)
    ELSE: RETURN
  ENDCASE

  ; Setup the continents if we need to plot them.
  IF mop.putcon THEN BEGIN
    xax = unit_vec(l0)
    yax = unit_vec(CROSSP(a_gci,l0))
    zax = unit_vec(CROSSP(xax,yax))
    lltopix_arr,clat,clon,emis_hgt,xax,yax,zax,o_gci,time,system,$
           ycon,xcon,acon,rotm
    rot_con,system,xcon,ycon,roti_val
    invalid = WHERE( acon LT (!DPI * 0.5D) )
    xcon( invalid ) = -101
    ycon( invalid ) = -101
  ENDIF

  IF mop.putgrd THEN BEGIN

    ; put image on screen
    CASE system OF
      1: BEGIN 
           lat = ROTATE(lat,2)
           lon = ROTATE(lon,2)
         END
      2: BEGIN
           lat = REVERSE(lat)
           lon = REVERSE(lon)
         END
      ELSE: RETURN
    ENDCASE

    lat = ROTATE(lat, roti_val)
    lon = ROTATE(lon, roti_val)

  ENDIF

END

;--------------------------------------------------------------

PRO final_prep_mlt, img

COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes

  ; white out outside the MLT dial
  sz = SIZE(img)
  nx = sz(1)
  ny = sz(2)
  cx = nx/2 - .5
  cy = ny/2 - .5
  rad2 = cx*cx
  FOR i=0,nx-1 DO BEGIN
    FOR j=0,ny-1 DO BEGIN
      dx = cx - i
      dy = cy - j
      IF (dx*dx + dy*dy GT rad2) THEN $
		img(i,j) = ct( cur_ct ).mlt_dial_fill
    ENDFOR
  ENDFOR

END

;--------------------------------------------------------------

FUNCTION tick_format, axis, index, ut_time

; Format for the tick labels: HH:MM

  hour = LONG(ut_time)
  minute = LONG(ROUND(60.*(ut_time-hour)))
  IF (minute EQ 60) THEN BEGIN
    hour = hour + 1
    minute = 0
  ENDIF
  RETURN, STRING(hour,minute,FORMAT="(i2.2,':',i2.2)")

END

;--------------------------------------------------------------

PRO plot_orbit,record,sslat,sslon

COMMON WINDINFO,main_windex,xmsg,ymsg,imsg,orbit_windex,model_windex
COMMON STRUCTURES
COMMON ORBIT,orb_gci,att_gci,gc_alt
COMMON CONSTANTS,earth_radius
COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum

WSET, orbit_windex

; plot the geocentric altitude
PLOT,ii.uthr,gc_alt/earth_radius, $
  YRANGE=[1.5,9.5], YSTYLE=1, YTITLE='GC Alt', $
  XRANGE=[0,24], XTICKS=4, XMINOR=6, $
  XSTYLE=1, $
  XTICKFORMAT='tick_format', XTICKLEN=0.06, $
  POSITION=[0.1,0.45,0.95,0.95],/NORMAL, $
  COLOR=mop.concol(mop.concolndx), $
  CHARSIZE=1.3

; place time and altitude cursor lines on the plot
time = ii(record).uthr
alt = gc_alt(record)/earth_radius
OPLOT,[time,time],[1.5,9.5],COLOR=red
OPLOT,[0,24],[alt,alt],COLOR=red

; write housekeeping string at bottom of window
rx = WHERE(recnum EQ record,crx)
IF (sslat GE 0.) THEN hem = 'N' ELSE hem = 'S'
IF (sslon GE 0.) THEN sem = 'E' ELSE sem = 'W'
hskpng = 'Door: ' + lb(rx).door_str + '  ' $
  + 'Gain: ' + lb(rx).gain_str + '  ' $
  + 'GC Alt: ' + STRING(alt,FORMAT='(F3.1)') + ' R!DE!N  ' $
  + 'Lat: ' + STRING(ABS(sslat),FORMAT='(I2)') + '!Uo!N ' + hem + '  ' $
  + 'Lon: ' + STRING(ABS(sslon),FORMAT='(I3)') + '!Uo!N ' + sem
XYOUTS,0.02,0.05,hskpng,/NORMAL, $
  COLOR=mop.concol(mop.concolndx), CHARSIZE=1.3

WSET, main_windex

END

;--------------------------------------------------------------

PRO img_map,record,image,cal_img,header,hskpng

COMMON CONSTANTS,earth_radius
COMMON AUXIL
COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON ORBIT,orb_gci,att_gci,gc_alt
COMMON PRNTINFO,geob,img_format,pict_index,sav_format
COMMON RECINFO, img_numrecs,begRec,endRec,curRec,recnum
COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz
COMMON STRUCTURES
COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes
COMMON IMAGES,raw_img
COMMON SCALE, min_log_scl,max_log_scl,amp,phi
COMMON STARS, td1
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag

; get system variable
system = ii(record).syst + 1

; get orbit and attitude vectors
o_gci = REFORM(orb_gci(*,record))
a_gci = REFORM(att_gci(*,record))

; Determine time array (must be type long)
time = LONARR(2)
time(0) = 1000L*ft(record).year + ft(record).doy
time(1) = (ft(record).hour*3600L + ft(record).minute*60L $
         + ft(record).second)*1000L

; produce rotation matrix: gci -> geo coordinates
ic_gci_to_geo,time,rotm

; get look direction
uvilook,time,o_gci,a_gci,ii(record).dspa,ii(record).filt, $
        versStr,l0,ra,dec,system=system
PRINT, 'Right ascension of look direction (in degrees):', ra
PRINT, 'Right ascension of look direction (in hours):  ', $
  dh_to_hmsm(ra/15.)
PRINT, 'Declination of look direction (in decimal degrees):', dec
PRINT, 'Declination of look direction (in deg:min:sec):  ', $
  dh_to_hmsm(dec)

; Correct boresight direction using stars
IF mop.stars[1] THEN correct_boresight,l0,a_gci,system,mop.ny,mop.nz

; *** print corrected right ascension and declination ***
IF mop.stars[1] THEN BEGIN
  vector_to_ra_dec, l0[0], l0[1], l0[2], ra, dec
  PRINT, 'Corrected right ascension of look direction:', ra
  PRINT, 'Corrected right ascension of look direction (in hours):  ', $
    dh_to_hmsm(ra/15.)
  PRINT, 'Corrected declination of look direction:', dec
  PRINT, 'Corrected declination of look direction (in deg:min:sec):  ', $
    dh_to_hmsm(dec)
ENDIF
; ***

; get lat lon
;ptg,system,time,l0,a_gci,o_gci,emis_hgt,lat,lon,/geodetic

; *** get latitude and longitude and right ascension and declination
; and geocentric X, Y, and Z position for each pixel ***
ptg, system, time, l0, a_gci, o_gci, emis_hgt, lat, lon, /GEODETIC, $
  /GETRA, RA = ra_arr, DEC = dec_arr, $
  POSX = posx, POSY = posy, POSZ = posz
; ***

; find the lat and lon for the subsatellite point
; and the radial position of the spacecraft
o_geo = TRANSPOSE(TRANSPOSE(rotm) # o_gci)
o_geo = unit_vec(o_geo)
sslat = ASIN(o_geo(2))/!DTOR
sslon = ATAN(o_geo(1),o_geo(0))/!DTOR
rsat = vec_norm(o_gci)
norm_rsat = rsat/earth_radius

; plot geocentric altitude and housekeeping in lower window
plot_orbit,record,sslat,sslon

; initialize dummy values
dayglo  = REPLICATE(0.,nxpix,nypix)
sza     = REPLICATE(0.,nxpix,nypix)
inv_los = REPLICATE(1.,nxpix,nypix)
los     = REPLICATE(1.,nxpix,nypix)

; find the LOS correction for all pixels
;doarealos = menu_value(1) + menu_value(2) + menu_value(4)
doarealos = menu_value(1) + menu_value(4)
IF (doarealos GT 0) THEN BEGIN
;print, 'Stopped before calling area_los'
;stop
  IF (ii(record).filt EQ 4) THEN $
    area_los,rsat,sslat,sslon,lat,lon,system,area,los,inv_los
; *** MOF 3/23/2005 ***
; add IF statement so large angle pixels are removed for non-LBHL filters
  IF (ii(record).filt NE 4) THEN BEGIN
    PRINT, 'Warning!  Performing LOS correction for filter ', $
      ii(record).filt
    area_los,rsat,sslat,sslon,lat,lon,system,area,los,inv_los, $
      NOT_LBHL = 1
  ENDIF
; ***
ENDIF

; create dayglow model image
; *** MOF 4/07/2004 ***
; calculate sza if saving structure
;dodayglow = menu_value(2) + menu_value(4)
dodayglow = menu_value(2) + menu_value(4) + sav_format[8]
IF (dodayglow GT 0) THEN BEGIN
; find the solar zenith angle for all pixels
  get_sza,ii(record).uthr,FIX(ft(record).year),FIX(ft(record).month), $
    FIX(ft(record).day),lat,lon,sza
  dodayglow2 = menu_value(2) + menu_value(4)
  IF (dodayglow2 GT 0) THEN BEGIN
; create an image dimensioned array of model dayglow values
    szang = FINDGEN(151)
    model = amp*cos(phi*szang*!dtor)^2
    dum = min(model,subs)
    model[subs:150] = 0.
    spl = SPL_INIT(szang,model)
    dayglo = SPL_INTERP(szang,model,spl,sza)
  ENDIF
ENDIF

image = ( image*inv_los - dayglo ) 
UNDEFINE,inv_los

sav_img = image

; transform image to MLT dial format
dosav = (FIX(TOTAL(sav_format(1:*))) + menu_value(4) + coor_value) < 1
IF dosav THEN BEGIN
  geo_to_apex,lat,lon,lat_mag,lon_mag,apexfile
  utsec = 3600L*ft(record).hour + 60L*ft(record).minute + ft(record).second
  mlt = get_mlt(ft(record).year,ft(record).doy,utsec,lon_mag,sslon)
  geo2mlt,image,lat_mag,mlt,mlt_img,alat,amlt,norm_rsat,record

  sav_mlt_img = mlt_img

ENDIF

IF sav_format(5) THEN BEGIN
  IF NOT DEFINED(mask) THEN RESTORE,mask_file
;  polar_cap_area, image, lat_mag, mlt, cap_array, bound_lat, bound_mlt,mask
  cap_studio, image, lat_mag, mlt, all_values, cap_array, mask
  IF NOT DEFINED(area) THEN BEGIN
      IF (ii(record).filt EQ 4) THEN $
        area_los,rsat,sslat,sslon,lat,lon,system,area,los,inv_los
  ENDIF
  pc(record).area = TOTAL(area*cap_array)*1e-6
  pc(record).ut = ii(record).uthr
  PRINT, pc(record).ut, pc(record).area
ENDIF

; IF sav_format[6] THEN get_uvi_at_fast, image, mlt, lat_mag, record

; calculate average flux for MLT bins
doflux = 0
IF menu_value(1) AND doflux THEN BEGIN
  flatmin = 60.
  flatmax = 78.
  mlt0 = 0.
  mlt1 = 24.
  IF (mlt1 LT mlt0) THEN nmlt = mlt1+24-mlt0 ELSE nmlt = mlt1-mlt0
  mlthour = FIX( (mlt0+INDGEN(nmlt)) MOD 24 )
  get_flux,image,lat_mag,mlt,flx_bin,flx_err,flatmin,flatmax,mlt0,mlt1
  ut = ii(record).uthr
  sav_filename = path.sav + 'flx_' + make_filetag(record) + '.sav'
  PRINT,'saving...',sav_filename
  SAVE,ut,flx_bin,flx_err,mlthour,flatmin,flatmax, FILENAME=sav_filename
ENDIF

tmp_lat = lat
tmp_lon = lon

; show right ascension and declination
IF mop.stars[0] THEN BEGIN

t = ft(record).hour + ft(record).minute/60. + ft(record).second/3600.

; restore TD-1 array if necessary
IF (N_ELEMENTS(td1) EQ 0) THEN BEGIN
  RESTORE, td1_file,/ver
ENDIF

year1 = 1950.
year2 = ft(record).year
doy2 = ft(record).doy
sod2 = ft(record).hour*3600. + ft(record).minute*60. + ft(record).second

k = 0
sav_col = 0
sav_row = 0
FOR i=0,(SIZE(td1))[1]-1 DO BEGIN
  corr_prec,year1,td1[i].ra,td1[i].dec,year2,doy2,sod2,ra2,dec2
  ratopix,ra2,dec2,l0,a_gci,system,row,col
  IF (ABS(col) LT 300) AND (ABS(row) LT 300) THEN BEGIN
;    print, 'yes'
    rot_con, system, col, row, roti_val
    mop.xl[k] = col
    mop.yl[k] = row
    mop.cl[k] = td1[i].expt+12.  ;-11 blue, -10 green, -9 red
; *** print ra and dec along with HD number ***
    mop.hd[k] = ' ' + STRCOMPRESS(td1[i].hd, /REMOVE_ALL) $
              + '!C' + '  ' + STRING(ra2, FORMAT = '(F6.2)') $
              + '/' + STRING(dec2, FORMAT = '(F6.2)')
    IF (td1[i].hd EQ 224686L) THEN BEGIN
      sav_col = col
      sav_row = row
      print, ra2, dec2, col, row
    ENDIF
;    IF (td1[i].hd EQ 175876L) THEN BEGIN
;      sav_col = col
;      sav_row = row
;      print, ra2, dec2, col, row
;    ENDIF
    k = k + 1
;    print, td1[i].hd, ' 2000 epoch', td1[i].ra, td1[i].dec
    IF (row GE -50 AND row LE 278 AND col GE -50 AND col LE 250) THEN $
      print, STRTRIM(td1[i].hd, 1), $
        '  ', STRTRIM(ra2, 1), $
        '  ', STRTRIM(dec2, 1), $
        '  ', STRTRIM(col, 1), $
        '  ', STRTRIM(row, 1)
  ENDIF
ENDFOR

bopp,record,ra_hb,dec_hb,comet_flag
IF comet_flag THEN BEGIN
  ratopix,ra_hb,dec_hb,l0,a_gci,system,row,col
  rot_con, system, col, row, roti_val
  mop.xl[k] = col
  mop.yl[k] = row
  mop.cl[k] = 3.
  mop.hd[k] = ' HB'
  k = k + 1
ENDIF
mop.nstars = k

ENDIF ; IF mop.stars[0]

IF coor_value EQ 0 THEN BEGIN
  scale_img, min, max, units, image
  final_prep_geo, system, image, l0, a_gci, o_gci, tmp_lat, tmp_lon, $
	xcon, ycon, rotm
  IF run_flag THEN $
  draw_geo, image, header, hskpng, record, rotm, a_gci, o_gci, l0, $
	tmp_lat, tmp_lon, xcon, ycon, min, max, sslat, sslon, pict=pict, $
        /USE_LAST_FOOTPOINT $
  ELSE $
  draw_geo, image, header, hskpng, record, rotm, a_gci, o_gci, l0, $
	tmp_lat, tmp_lon, xcon, ycon, min, max, sslat, sslon, pict=pict
END ELSE BEGIN
  scale_img, min, max, units, mlt_img
  img_bound,lat_mag,mlt,xfov,yfov
  draw_mlt,mlt_img,header,hskpng,record,min,max,xfov,yfov
END

; SAVE FILES

; calibration unit scaling
unit_conversion = [1., 30.166, 30.166/110.]
cal_ext = ['p','r','e']

; Save Geographic, lat & lon
IF( sav_format(0) ) THEN BEGIN
;  image = cal_img*unit_conversion(cal_unit)
  image = sav_img
  filter = ii(record).filt
  rate = ii(record).rate
  ut = ii(record).uthr
  sav_filename = path.sav + make_filetag(record) + $
                 '_g' + cal_ext(cal_unit) + '.sav'
  SAVE, filter, rate, ut, image, lat, lon, FILENAME=sav_filename
  PRINT,'Saving ',sav_filename,'......'
END  

; Save Magnetic, lat_mag & mlt
IF sav_format(1) THEN BEGIN
;  image = cal_img*unit_conversion(cal_unit)
  image = sav_img
  filter = ii(record).filt
  rate = ii(record).rate
  ut = ii(record).uthr
  sav_filename = path.sav + make_filetag(record) + '_a.sav'
  SAVE, filter, rate, ut, image, lat_mag, mlt, FILENAME=sav_filename

  PRINT,'Saving ',sav_filename,'......'

  sav_filename = path.sav + make_filetag(record) + '_raw.sav'
  SAVE, raw_img, bkg_img, los, sza, FILENAME=sav_filename
  PRINT,'Saving ',sav_filename,'......'

ENDIF

; Save binned MLT for keogram
IF sav_format(2) THEN BEGIN
  binmlt,sav_img,mlt,lat_mag,nmlt,nlat,mlt_bin
  image = mlt_bin   ;  *unit_conversion(cal_unit)
  rx = WHERE(recnum EQ record,crx)
  filter_str = lb(rx).filter_str
  int_per_str = lb(rx).ip_str
  ut = ii(record).uthr
  latmin = mop.latmin
  sav_filename = path.sav + make_filetag(record) + '_k.sav'
  SAVE,filter_str,int_per_str,ut,nmlt,nlat,image, $
       latmin, FILENAME=sav_filename
  PRINT,'Saving ',sav_filename,'......'
ENDIF

; Save calibrated image
IF( sav_format(3) ) THEN BEGIN
;  image = cal_img*unit_conversion(cal_unit)
  image = sav_img
  filter = ii(record).filt
  rate = ii(record).rate
  ut = ii(record).uthr
  sav_filename = path.sav + make_filetag(record) + '_c.sav'
SAVE,filter,rate,ut,image,raw_img,FILENAME=sav_filename
;col = sav_col
;row = sav_row
;col = 199. - col/(227./199.)
;SAVE,filter,col,row,rate,ut,image,raw_img,FILENAME=sav_filename
;SAVE,filter, col,row,rate, ut, image, raw_img, sza, los, dayglo, $
;    FILENAME=sav_filename
  PRINT,'Saving ',sav_filename,'......'
END  

; Save transformed MLT image
IF sav_format(4) THEN BEGIN
  mlt_img = sav_mlt_img
  rx = WHERE(recnum EQ record,crx)
  filter_str = lb(rx).filter_str
  int_per_str = lb(rx).ip_str
  ut = ii(record).uthr
  unit_str = 'Photon flux  photon cm^-2 s^-1'
  sav_filename = path.sav + make_filetag(record) + '_m.sav'
  SAVE,filter_str,unit_str,int_per_str,ut,alat,amlt,mlt_img, $
      FILENAME=sav_filename
  PRINT,'Saving ',sav_filename,'......'
ENDIF

; print gif image
IF (img_format(0)) THEN BEGIN
  gif_filename = path.gif + make_filetag(record)

  IF coor_value EQ 1 THEN BEGIN
    gif_filename = gif_filename + '_a.gif'
    IF (show_cbar) THEN gifx = xwin $
      ELSE gifx = 2*border + img_siz
    gify = ywin
  END ELSE BEGIN 
    gif_filename = gif_filename + '.gif'
    IF (show_cbar) THEN gifx = 5*border + nypix + xcbar $
      ELSE gifx = 2*border + nypix
    gify = 2*border + nypix + ylabl
  END

  WRITE_GIF, gif_filename, TVRD(0,0,gifx,gify),$
 	ct(cur_ct).rct, ct( cur_ct ).gct, $
 	ct( cur_ct).bct

ENDIF

IF (img_format(1)) THEN BEGIN
  ps_filename = path.psc + make_filetag(record)
  IF coor_value EQ 0 THEN ps_filename = ps_filename + '_g.ps' $
  ELSE ps_filename = ps_filename + '_a.ps'

  oldDevice = !D.NAME

  SET_PLOT, 'ps'
; *** MOF 7/28/2003 ***
; add EPS option
; comment out next line and add the line following: ENCAPS = 0
;  DEVICE, /PORTRAIT, /COLOR, BITS=8, $
  DEVICE, /PORTRAIT, /COLOR, BITS=8, ENCAPSULATED = 0, PREVIEW = 0, $
; ***
    FILENAME=ps_filename, /TIMES, $
    YSIZE=ps.cm, XSIZE=ps.cm, XOFFSET=ps.xoff, YOFFSET=ps.yoff
  color_value_rgb

  IF coor_value EQ 0 THEN BEGIN
    draw_geo, image, header, hskpng, record, rotm, a_gci, o_gci, l0, $
	tmp_lat, tmp_lon, xcon, ycon, min, max, sslat,sslon, pict=pict, $
	/IS_PS, /USE_LAST_FOOTPOINT
  END ELSE BEGIN
    draw_mlt,mlt_img,header,hskpng,record,min,max,xfov,yfov, $
      /IS_PS,/USE_LAST_FOOTPOINT
  END

  DEVICE,/CLOSE_FILE
  SET_PLOT, oldDevice
ENDIF

; *** MOF 7/28/2003 ***
; add EPS option
; add this entire section
IF (img_format(2)) THEN BEGIN
  eps_filename = path.psc + make_filetag(record)
  IF coor_value EQ 0 THEN eps_filename = eps_filename + '_g.eps' $
  ELSE eps_filename = eps_filename + '_a.eps'

  oldDevice = !D.NAME

  SET_PLOT, 'ps'
  DEVICE, /PORTRAIT, /COLOR, BITS=8, ENCAPSULATED = 1, PREVIEW = 1, $
;  DEVICE, /PORTRAIT, /COLOR, BITS=8, $
    FILENAME=eps_filename, /TIMES, $
    YSIZE=ps.cm, XSIZE=ps.cm, XOFFSET=ps.xoff, YOFFSET=ps.yoff
  color_value_rgb

  IF coor_value EQ 0 THEN BEGIN
    draw_geo, image, header, hskpng, record, rotm, a_gci, o_gci, l0, $
	tmp_lat, tmp_lon, xcon, ycon, min, max, sslat,sslon, pict=pict, $
	/IS_PS, /USE_LAST_FOOTPOINT
  END ELSE BEGIN
    draw_mlt,mlt_img,header,hskpng,record,min,max,xfov,yfov, $
      /IS_PS,/USE_LAST_FOOTPOINT
  END

  DEVICE,/CLOSE_FILE
  SET_PLOT, oldDevice
ENDIF
; ***

IF sav_format(7) THEN BEGIN
  power = area*sav_img*30.166/110.*1.e-6     ; 10^10 * 10^-16
  pndx = WHERE(lat_mag GT mop.latmin, count)
  IF (count GT 0) THEN ap[record].power = TOTAL(power[pndx]) $
    ELSE ap[record].power = 0.
  ap[record].ut = ii(record).uthr
  print, 'Total power (saved to file when sequence is run) = ', ap[record].power
ENDIF

IF menu_value(4) THEN BEGIN
  dmlt = 0.25
  nmlt = 24./dmlt
  latmax = 90.
  dlat = 0.25
  nlat =  FIX((latmax - mop.latmin)/dlat)
  nrg = FLTARR(nmlt,nlat)
  sum = FLTARR(nmlt,nlat)
  
  ; create energy flux image map
  power = area*sav_img*30.166/110.*1.e-6     ; 10^10 * 10^-16

mlt0 = 0.
mlt1 = 24.
lat0 = 70.
lat1 = 90.
read,'enter: mlt0 mlt1 lat0 lat1',mlt0,mlt1,lat0,lat1
IF (mlt0 GT mlt1) THEN BEGIN
  pndx = WHERE( ((mlt GE mlt0) OR (mlt LT mlt1)) AND $
                (lat_mag GE lat0) AND (lat_mag LT lat1), count )
ENDIF ELSE BEGIN
  pndx = WHERE( (mlt GE mlt0) AND (mlt LT mlt1) AND $
                (lat_mag GE lat0) AND (lat_mag LT lat1), count )
ENDELSE

IF (count GT 0) THEN tot_power = TOTAL(power[pndx]) ELSE tot_power = 'N/A'
  
  print,'total power ',tot_power

ENDIF

; *** MOF 4/7/2004 ***
; save big structure with lots of data

IF sav_format[8] THEN BEGIN
; define some quantities that will go into the structure
  ncols = 200
  nrows = 228

  CASE system OF
    1: BEGIN
         pc = 0.03987D  ; W. Swift 10/97
         pr = 0.03380D  ; W. Swift 10/97
       END
    2: BEGIN
         pc = 0.04178D  ; W. Swift 10/97
         pr = 0.03511D  ; W. Swift 10/97
;         pc = 0.04159D ; W. Peria 7/28/00
;         pr = 0.03384D ; W. Peria 7/28/00
       END
  ENDCASE

  rx = WHERE(recnum EQ record, crx)
  ip_str = lb(rx).ip_str
  filter_str = lb(rx).filter_str
  CASE cal_unit OF
    0: unitstr = 'photons cm^-2 s^-1'
    1: unitstr = 'Rayleighs'
    2: unitstr = 'ergs cm^-2 s^-1'
    ELSE: unitstr = 'unknown'
  ENDCASE

; calculate spacecraft zenith angles (dza)
  slpixx = posx - o_gci[0]
  slpixy = posy - o_gci[1]
  slpixz = posz - o_gci[2]
  dot_product = slpixx*posx + slpixy*posy +slpixz*posz
  mag_pos = SQRT(posx*posx + posy*posy + posz*posz)
  mag_slpix = SQRT(slpixx*slpixx + slpixy*slpixy + slpixz*slpixz)
  off_earth = WHERE(mag_slpix LE 0., num_off_earth)
  IF (num_off_earth GT 0) THEN mag_slpix[off_earth] = 1. ; avoid / 0.
  dza = ACOS(dot_product/mag_pos/mag_slpix)/!DTOR
  IF (num_off_earth GT 0) THEN dza[off_earth] = -1.D31

; create and fill structure (all angles in degrees)
  uvi_info = {imagedata, $
    date:time[0], $        ; longword integer date (yyyyddd)
    time:time[1], $        ; longword integer time (at start of IP)
    cols:ncols, $          ; number of columns
    rows:nrows, $          ; number of rows
    system:system, $       ; 1 = primary, 2 = secondary
    raw:raw_img, $         ; raw image (in bytes?)
;    bkg: , $               ; background image
;    flatf: , $             ; flat field
    image:cal_img, $       ; calibrated image (no corrections)
    units:unitstr, $            ; units of calibrated image
    a_gci:a_gci, $         ; attitude vector
    o_gci:o_gci, $         ; orbit vector
    ip:ip_str, $           ; string (integration period in seconds)
;   ip:0. , $              ; integration period in seconds
    filter:filter_str, $   ; string (filter)
;   filter:filter, $       ; 1 = 1304, 2 = 1356, 3 = LBHS, 4 = LBHL
    l0:l0, $               ; look direction of center of FOV
    ang_res_c:pc, $        ; angular resolution of columns
    ang_res_r:pr, $        ; angular resolution of rows
    ra:ra_arr, $           ; right ascension of each pixel
    dec:dec_arr, $         ; declination of each pixel
    glat:lat, $            ; geographic latitude of each pixel
    glon:lon, $            ; geographic longitude of each pixel
    mlat:lat_mag, $        ; magnetic (apex) latitude of each pixel
    mlon:lon_mag, $        ; magnetic longitude (apex) of each pixel
    mlt:mlt, $             ; magnetic local time (apex) of each pixel
    sza:sza, $             ; solar zenith angle of each pixel
    dza:dza, $             ; spacecraft zenith angle of each pixel
    emis_hgt:emis_hgt}     ; assumed emission height

  sav_filename = path.sav + make_filetag(record) + '_structure.sav'
  SAVE, uvi_info, $
    FILENAME = sav_filename
  PRINT, 'Saving ', sav_filename, '...'

ENDIF
; ***

END

;--------------------------------------------------------------
;
; include FAST oplot stuff here...
;
;@/usr/local/idluvi/studio/overplot_fast_orbit

PRO studio

; 30 August 2000 Last revision 
;versionstr = 'Studio 6.2'  

; 21 August 2000 Last revision 
; added refresh feature to model dayglow
; added star HD designations
; added boresight correction
; versionstr = 'Studio 6.3'

; June 2006 - Fast orbit overlay option removed
  versionstr = 'Studio 6.4'

COMMON CONSTANTS,earth_radius
COMMON STATIC,nxpix,nypix,border,ylabl,xcbar,charsiz,xwin,ywin,img_siz
COMMON WIDGID,base,brec,erec,enhs,forw,revr,rnsq,wlst,menu, $
  coor,scal,cbar,dglo,prto,minl,maxl,pszw,ampv,phiv
COMMON IMGINFO, filseq,ipseq,roti_val,enhance,scal_value, $
  cal_unit,scale,menu_value,coor_value,mark_val,markll,stncd,show_cbar
COMMON FLAGS, file_flag,run_flag,list_flag,seqc_flag
COMMON STRUCTURES
COMMON WINDINFO,main_windex,xmsg,ymsg,imsg,orbit_windex,model_windex
COMMON UCOLORS,green,white,blue,red,black,top_color, $
	ct,cur_ct,num_schemes
COMMON SEQINFO,beg_seq_rec,end_seq_rec
COMMON PRNTINFO,geob,img_format,pict_index,sav_format
COMMON EDIT_PATHS,selected_path,ptxt,slpb,paths
COMMON SCALE, min_log_scl,max_log_scl,amp,phi

; check read paths
path.aux = check_for_backslash(path.aux)
path.img = check_for_backslash(path.img)
path.orb = check_for_backslash(path.orb)
path.att = check_for_backslash(path.att)
path.dsp = check_for_backslash(path.dsp)
path.nrt = check_for_backslash(path.nrt)

; check write paths
path.psc = check_for_backslash(path.psc)
path.gif = check_for_backslash(path.gif)
path.sav = check_for_backslash(path.sav)

; initialize auxiliary files
load_files

; structures for beginning and ending sequence of images
begep = {beg_epoch, YEAR: 0, MONTH: 0, DAY: 0, HOUR: 0, $
   MINUTE: 0, SECOND: 0, DOY: 0, DOP: 0}
endep = {end_epoch, YEAR: 0, MONTH: 0, DAY: 0, HOUR: 0, $
   MINUTE: 0, SECOND: 0, DOY: 0, DOP: 0}

; this parameter adjusts the intensity range of the displayed image
; changing this value will cause calibration errors
scale = 0.004

; initialize constants
earth_radius = 6371.D

; set 8-bit color on a true color display
; device, pseudo_color = 8
; device, decompose = 0

; initialize color table
color_value_rgb

; initialize calibration
init_calib

; map widget structure inititialization
nstars = 1050
mop = {mapop, PUTCON: 1, PUTGRD: 1, PUTLAB: 1, $
       CONCOL: [black,blue,red,white,green], $
       GRDCOL: [black,blue,red,white,green], $
       CONCOLNDX: ct(cur_ct).cont_idx, $
       GRDCOLNDX: ct(cur_ct).glat_idx, $
       LATDEL: 10, LONDEL: 45, $
       FOV: 0, LATMIN: 60, $
       STARS: [0,0], NSTARS: nstars, $
       XL: FLTARR(nstars), YL: FLTARR(nstars), CL: FLTARR(nstars), $
       HD: STRARR(nstars), NY: 0, NZ: 0}
; postscript parameters structure
ps = {post, CM: 7.0, XOFF: 7.0, YOFF: 10.0, $
      HEADER: 0.875, GLABEL: 0.84, CBTEXT: 0.98}

; initialize flags
file_flag = 0
run_flag = 0
list_flag = 1
seqc_flag = 0

; static constants and variables
nxpix = 200
nypix = 228
nmltp = 240
enhance = 100
border = 10
ylabl = 10
xcbar = 40
xwin = nmltp + xcbar + 5*border
ywin = nmltp + 2*ylabl + 2*border
nmsg = 10
imsg = 0
xmsg = REPLICATE(20,nmsg)
ymsg = ywin - 20*(INDGEN(nmsg) + 1)
IF !VERSION.OS EQ 'Win32' THEN charsiz = 1.2 ELSE charsiz = 1.5

; mark location widget
mark_val = 0
markll = FLTARR(2,7)
stncd = STRARR(7)

; print widget initialization
; *** MOF 7/28/2003 ***
; add EPS option
; add another digit (is this necessary?)
;img_format = [0,0,0]
img_format = [0,0,0,0]
; ***
; *** MOF 4/07/2004 ***
; add save structure option
;sav_format = [0,0,0,0,0,0,0,0]
sav_format = [0,0,0,0,0,0,0,0,0]
; ***
pict_index = 0

; path widget initialization
selected_path = 0

;Initialize Widgets
filt_dplist = ['LBHL        ','LBHS','1356','1304','SOLR', $
               'ALL ','HOME','SHUT','LBH']
intp_dplist = ['ALL         ','36.8','18.4','9.2','3.0','1.5']
roti_dplist = ['NORM     ','90','180','270']
unit_dplist = ['Photon Flux ','Rayleighs','Energy Flux']
clr_dplist = ['Standard','Black Rainbow', 'Rainbow', 'Blue Red', $
              'Black Blue Red','Black & White']
mark_dplist = [' 1 ',' 2 ',' 3 ',' 4 ',' 5 ',' 6 ',' 7 ']
; *** MOF 7/28/2003 ***
; add EPS option
;print_items = ['gif  ','ps']
print_items = ['gif  ','ps  ', 'eps']
; ***
; menu_items = ['Clean Image','LOS Correction','Remove Dayglow', $
;         'KC Dewobble','Energy Flux','Filter','Mark ' + $ 
;               'Location','Show FAST footpoint']
; menu_value = [0,0,0,0,0,0,0,0]
 menu_items = ['Clean Image','LOS Correction','Remove Dayglow', $
         'KC Dewobble','Energy Flux','Filter','Mark ' + $ 
               'Location']
 menu_value = [0,0,0,0,0,0,0]
coor_dplist = ['Geographic','MLT (APEX)']
coor_value = 0
show_cbar = 1
scal_optns = ['Log','Linear']
scal_value = 0
beg_seq_rec = 0
end_seq_rec = 0
cal_unit = 0   ; photon flux
min_log_scl = 3.0
max_log_scl = 300.0
filseq = 4
ipseq = 0
roti_val = 0
datstr = [' ',' ']
amp = 76.
phi = 0.83

; parent
base = WIDGET_BASE(/ROW,TITLE=versionstr)

; child 1 (chi1)
chi1 = WIDGET_BASE(base,/COLUMN)
quit = WIDGET_BUTTON(chi1,UVALUE=0,VALUE='Quit')
getf = WIDGET_BUTTON(chi1,VALUE='Select File...',EVENT_PRO='selectFile_event')
mapo = WIDGET_BUTTON(chi1,VALUE='Plot Options...',EVENT_PRO='mapop_event')
savo = WIDGET_BUTTON(chi1,VALUE='Save Options...',EVENT_PRO='save_event')
ptho = WIDGET_BUTTON(chi1,VALUE='Path Options...',EVENT_PRO='path_event')
dglo = WIDGET_BUTTON(chi1,VALUE='Model Dayglow', $
         EVENT_PRO='model_dayglow_event')
roti = WIDGET_DROPLIST(chi1,UVALUE=4,VALUE=roti_dplist,TITLE='Orient: ')
filt = WIDGET_DROPLIST(chi1,UVALUE=6,VALUE=filt_dplist,TITLE='Filter:  ')
intp = WIDGET_DROPLIST(chi1,UVALUE=5,VALUE=intp_dplist,TITLE='I P:       ')
unit = WIDGET_DROPLIST(chi1,UVALUE=7,VALUE=unit_dplist,TITLE='Units:   ')
colr = WIDGET_DROPLIST(chi1,UVALUE=42,VALUE=clr_dplist,TITLE='Colors:  ')
coor = WIDGET_DROPLIST(chi1,UVALUE=14,VALUE=coor_dplist,TITLE='Coordinates:')

; step child 0
stc0 = WIDGET_BASE(chi1,/ROW,FRAME=5)
prto = CW_BGROUP(stc0, UVALUE=43, print_items, /ROW, /NONEXCLUSIVE)
pszw = CW_FIELD(stc0,UVALUE=44,VALUE=ps.cm,TITLE='cm:', $
  XSIZE=5,/ROW,/FLOATING,/ALL_EVENTS)

; step child 1
stc1 = WIDGET_BASE(chi1,/COLUMN,FRAME=5)
menu = CW_BGROUP(stc1,UVALUE=8,/COLUMN,/NONEXCLUSIVE,menu_items, $
         SET_VALUE=menu_value)
mkdl = WIDGET_DROPLIST(stc1,UVALUE=1,VALUE=mark_dplist,TITLE='How many?')

; child 2 (chi2)
chi2 = WIDGET_BASE(base,/COLUMN)
wdw1 = WIDGET_DRAW(chi2,XSIZE=xwin,YSIZE=ywin)

; grandchild 1
gch1 = WIDGET_BASE(chi2,/ROW)
begr = WIDGET_BUTTON(gch1,UVALUE=11,VALUE='  |<  ')
revr = WIDGET_BUTTON(gch1,VALUE='  <<  ',EVENT_PRO='reverse_event')
decr = WIDGET_BUTTON(gch1,UVALUE=2,VALUE='  <  ')
incr = WIDGET_BUTTON(gch1,UVALUE=3,VALUE='  >  ')
forw = WIDGET_BUTTON(gch1,VALUE='  >>  ',EVENT_PRO='forward_event')
endr = WIDGET_BUTTON(gch1,UVALUE=12,VALUE='  >|  ')

; grandchild 2
gch2 = WIDGET_BASE(chi2,/ROW,FRAME=5)
rnsq = WIDGET_BUTTON(gch2,VALUE='   Run Sequence   ', $
         EVENT_PRO='run_sequence_event')
brec = CW_FIELD(gch2,UVALUE=15,TITLE='From:',VALUE=beg_seq_rec, $
  XSIZE=8,/COLUMN,/INTEGER,/ALL_EVENTS)
erec = CW_FIELD(gch2,UVALUE=16,TITLE='To:',VALUE=end_seq_rec, $
  XSIZE=8,/COLUMN,/INTEGER,/ALL_EVENTS)

; grandchild 3
gch3 = WIDGET_BASE(chi2,/ROW,FRAME=5)
ggc1 = WIDGET_BASE(gch3,/COLUMN)
scal = CW_BGROUP(ggc1,UVALUE=18,/COLUMN,/EXCLUSIVE,scal_optns, $
         SET_VALUE=0)
cbar = CW_BGROUP(ggc1,UVALUE=17,/ROW,/NONEXCLUSIVE,['Color Bar'], $
         SET_VALUE=1)

; great grandchild 2
ggc2 = WIDGET_BASE(gch3,/COLUMN)

; great grandchild 3
ggc3 = WIDGET_BASE(ggc2,/ROW)
minl = CW_FIELD(ggc3,UVALUE=20,TITLE='Min:',VALUE=min_log_scl, $
  XSIZE=8,/ROW,/FLOATING,/ALL_EVENTS)
maxl = CW_FIELD(ggc3,UVALUE=21,TITLE='Max:',VALUE=max_log_scl, $
  XSIZE=8,/ROW,/FLOATING,/ALL_EVENTS)
enhs = WIDGET_SLIDER(ggc2,UVALUE=9,VALUE=100, $
   MINIMUM=1,MAXIMUM=400)
xwin2 = 450
ywin2 = 100
wdw2 = WIDGET_DRAW(chi2,XSIZE=xwin2,YSIZE=ywin2)

ggc4 = WIDGET_BASE(chi2,/ROW,FRAME=5)
ampv = CW_FIELD(ggc4,UVALUE=30,TITLE='amp:',VALUE=amp, $
  XSIZE=8,/ROW,/FLOATING,/ALL_EVENTS)
phiv = CW_FIELD(ggc4,UVALUE=31,TITLE='phi:',VALUE=phi, $
  XSIZE=8,/ROW,/FLOATING,/ALL_EVENTS)
oplw = WIDGET_BUTTON(ggc4,VALUE='Refresh Model', $
         EVENT_PRO='refresh_model_event')

; child 3 (chi3)
chi3 = WIDGET_BASE(base,/COLUMN)
font = 'courier'
sz = [31,42]
;sz = [18,32]
wlst = WIDGET_LIST(chi3,UVALUE=13,VALUE=datstr,YSIZE=sz(1),XSIZE=sz(0), $
    FONT=font)

;Produce the interface tool

WIDGET_CONTROL, base, /REALIZE
WIDGET_CONTROL, GET_VALUE=main_windex, wdw1
WIDGET_CONTROL, GET_VALUE=orbit_windex, wdw2

;Hand-off control to the event manager

XMANAGER, 'studio', base,/NO_BLOCK

END