;+
; Name: grs_make_bk_files
;
; Purpose: For SMM GRS (and GRS HEM) data, create background save files appropriate for use in OSPEX to
;   analyze the GRS flare data.
;
; Explanation:
;  The UNH-provided GRS files (.USE files https://umbra.nascom.nasa.gov/pub/smm/smmgrs/solar_flare/)
;  were converted to FITS files and stored on https://hesperia.gsfc.nasa.gov/smm/grs/
;  The .USE files (and the FITS files) are named with a flare designation
;  in the first five characters followed by FD (flare data), DB (day before), or DA (day after),
;  e.g. F8105_FD for flare data for year 1988, doy 105).
;  The DB and DA files provide background rates at the ~same orbital locations as the FD file,
;  however they seem to vary unexpectedly in length, and proper overlap of orbital location as the FD.
;  In addition to covering the same orbital location, the background array must be the same dimensions
;  in time and energy as the FD data to use in OSPEX (SSW spectral analysis tool).
;
;  To ensure proper background data, Gerry Share examined each of the FD,DB,DA sets, and
;  determined which are usable, and what time intervals in each should be used.  This information is
;  stored in  the save file grs_dba_times.sav.
;  Using that file as a guide for times to use for each file (or whether the file can be used at all),
;  we accumulate the FD, DA, and DB data.  Because of slight variations in SAA start etc, there might
;  be different numbers of bins in each, so we adjust them to be the same by either truncating the
;  background arrays, or extending them by repeating the last element.
;  If both DB and DA are available, we average them (and combined errors in quadrature), if only one
;  is available then that is the background.
;
;  The save files contain these variables:
;  readme - text string with explanation of variables
;  fd_file_name - name of FD file that this background applies to
;  fd_accum_time - time interval of fd_file_name to use
;  back_grs - [nenergy, ntime] array of background data in counts/sec
;  eback_grs - [nenergy, ntime] array of error in background data in counts/sec
;  use_db - 1 if day before file was used (if use_da also set, then bk is average of the two)
;  use_da - 1 if day after file was used (if use_db also set, then bk is average of the two)
;
; Written: 9-Apr-2019, Kim Tolbert
; Modifications:
;  12-Jun-2019, Kim. Added ability to write HEM background save files
;-

function grs_fix_bk_array, bk, ndd

  nbk = n_elements(bk.data[0,*])
;  print,'grs_fix_bk_array ndd,nbk, ', ndd, nbk
  
  ; if number of points in bk data doesn't equal number of points in flare data, either truncate, or extend bk array
  if nbk ne ndd then begin
    bkdata = bk.data
    bkedata = bk.edata

    if nbk gt ndd then begin
      bkdata = bkdata[*,0:ndd-1]
      bkedata = bkedata[*,0:ndd-1]
    endif else begin
      need = ndd - nbk
      bkdata =  [ [bkdata],  [reproduce(bkdata[*,-1], need)] ]
      bkedata = [ [bkedata], [reproduce(bkedata[*,-1], need)] ]
    endelse
    bk = {data: bkdata, edata: bkedata} ; we'll leave ltime out - don't need here anyway.
  endif

  return, bk

end


pro grs_make_bk_files, hem=hem

checkvar, hem, 0

  ; restore structure containing times to use from FD, DB, and DA files to create background 
  restore, file='grs_dba_times.sav', /verbose
  nf = n_elements(out_dba)

  type = hem ? 'SMM GRS HEM': 'SMM GRS' 
  readme = ['These ' + type + ' background save files were written in June 2019 by Kim Tolbert.', $
    'See the header doc for grs_make_bk_files.pro for more details.', $
    'The save files contain these variables:', $
    '  readme - this text string of explanation', $
    '  fd_file_name - name of FD file that this background applies to', $
    '  fd_accum_time - time interval of fd_file_name to use in sec since 1979/1/1', $
    '  back_grs -  [nenergy, ntime] array of background data in counts/sec', $
    '  eback_grs - [nenergy, ntime] array of error in background data in counts/sec', $
    '  use_db - 1 if day before file was used (if use_da also set, then bk is average of the two)', $
    '  use_da - 1 if day after file was used (if use_db also set, then bk is average of the two)', $
    'If the fd_file_name is accumulated in OSPEX for the time interval in fd_accum_time, then', $
    'back_grs, eback_grs have the correct dimensions to use in the replacedata method in OSPEX.']

  for ii=0,nf -1 do begin
    z = out_dba[ii]
    print, ' '
    print, 'Working on ' + z.usename
    fd = file_search('/data/smm/grs/', 'smm_grs_*' + z.usename + '*FD.fits', count=nfd)
    fb = file_search('/data/smm/grs/', 'smm_grs_*' + z.usename + '*DB.fits', count=nfb)
    fa = file_search('/data/smm/grs/', 'smm_grs_*' + z.usename + '*DA.fits', count=nfa)

    obj = ospex(/no_gui)

    ; First accumulate flare data to see how many bins there are
    obj->set, spex_specfile=fd
    obj->set, spex_accum_time=z.fd_use_time
    if hem then obj->set, spex_data_sel='hem' else obj->set, spex_datasel=''
    
    dd = obj->getdata(spex_units='rate')
    ndd = n_elements(dd.data[0,*])

    ; If there is a DB file, and the accum time specified is not 0., get db data and adjust size to flare data
    if nfb gt 0 && z.db_use_time[0] ne 0. then begin
      obj->set, spex_specfile=fb
      obj->set, spex_accum_time=z.db_use_time
      db = obj->getdata(spex_units='rate')
      db = grs_fix_bk_array(db, ndd)
      use_db = 1
    endif else use_db = 0

    ; If there is a DA file, and the accum time specified is not 0., get da data and adjust size to flare data
    if nfa gt 0 && z.da_use_time[0] ne 0. then begin
      obj->set, spex_specfile=fa
      obj->set, spex_accum_time=z.da_use_time
      da = obj->getdata(spex_units='rate')
      da = grs_fix_bk_array(da, ndd)
      use_da = 1
    endif else use_da = 0

    ;Average DB and DA if both are available
    if use_db and use_da then begin
      back_grs = (db.data  + da.data) / 2.
      eback_grs = ( sqrt(db.edata^2 + da.edata^2) ) / 2.
    endif else if use_db then begin
      back_grs = db.data
      eback_grs = db.edata
    endif else if use_da then begin
      back_grs = da.data
      eback_grs = da.edata
    endif

    if use_db or use_da then begin
      save_file = str_replace(fd, '.fits', '_background.sav')
      if hem then save_file = str_replace(save_file, 'smm_grs', 'smm_grs_hem')
      fd_file_name = file_basename(fd)
      fd_accum_time = z.fd_use_time
      save, file=save_file, readme, fd_file_name, fd_accum_time, back_grs, eback_grs, use_db, use_da
      print,'Wrote ', save_file
    endif else print,'No background.  Did not write background save file.'

    destroy,obj

  endfor

end