;+
; NAME: sotsp_l12voe
;
; PURPOSE: Given an input SOT-SP Level 1.5 ("level1d") directory, with four
;          FITS files corresponding to the level 1.5 outputs, this routine
;          will return an IDL structure that can be saved as a VOEvent XML
;          file by mk_voe_obs.pro and ingested into the HCR by
;          ssw_coverage_ingest.pro
;
; CALLING SEQUENCE: result=sotsp_l12voe(l1dir,outdir=voedir,/ingest)
;
; INPUTS: l1dir = a single SOT-SP Level 1.5 directory
;         outdir = keyword containing an output directory for XML file
;
; KEYWORD PARAMETERS:
;         ingest = a switch that, if set, will ingest the newly created VOEvent
;                  into the HCR
;         debug = a switch that, if set, will stop the routine before the
;                 ingest step
;         context_redo = a switch that, if set, will remove and re-create the
;                        context images in the Level 1.5 directory
;
; OUTPUTS: an IDL structure characterizing the Level 1.5 data that can be used
;          as input to mk_voe_obs.pro
;
; MODIFICATION HISTORY:
;          2008/9-ish - maybe G.L.Slater? - created
;          2021-04-15 - M.DeRosa - version 1.1 - added doc header and some
;                                  comments
;          2021-12-09 - M.DeRosa - version 1.2 - routine now uses -9999 as the
;                       indicator for a missing slit position (formerly, -99
;                       was used, but this can be a valid slit position)
;          2024-09-19 - M.DeRosa - version 2.0 - added the following elements
;                       to the VOEvent for ingestion: SCAN_ID, PROG_VER,
;                       SEQN_VER, PARM_VER, PROG_NO, SEQN_NO, NSLITPOS,
;                       SPNINT, NUM_SIDE, SCN_STEP, SCN_SUM, SCN_RPT, WEDGE,
;                       FOCUS, NLEV1FILES, LEV1COMPLETIONRATIO
;
;-
function sotsp_l12voe,l1dir, outdir=outdir, ingest=ingest, debug=debug, $
  context_redo=context_redo, fwave=fwave

version=2.0  ;  version number
  
debug=keyword_set(debug)

;  template for output structure
tempfile='$SSW/hinode/sot/idl/sp/util_lmsal/sotsp_voestruct_template.geny'
restgenx,file=tempfile, retval

;  get list of the four FITS files from the level 1.5 directory
fits=file_search(l1dir,'*fits')
if n_elements(fits) ne 4 then begin 
  box_message,'Expected 4 fits files, no more, no less...'
  return,-1
endif 
fits=fits[[2,1,3,0]]

;  read in the FITS files and harvest some header data
mreadfits,fits,index,data
date_obs=index(0).date_obs ; used for all
date_end=index(0).date_end
t0=date_obs & t1=date_end
dt=ssw_deltat(t0,t1,/sec) 

;  do a Level 0 catalog search to get observing modes
sot_cat,date_obs,date_end,cat,search='obsdir=SP4D',/level0
if data_chk(cat,/struct) then begin  

  ;  restrict catalog to most common SP mode
  umodes=sot_umodes(cat,mcount=mcount)
  if n_elements(umodes) gt 1 then begin
    box_message,'More than one SP Mode?? - using max'
    ss=where(mcount eq max(mcount))
    sss=sot_umodes(cat,where_mode=umodes(ss(0)))
    cat=cat(sss)
    umodes=umodes(ss(0))
  endif

  ;  determine scan rate and (if a repeating scan) the repeat cadence
  slitpos=gt_tagval(cat,/slitpos,missing=-9999)
  hpos=histogram([slitpos])
  ssm=where(slitpos eq -9999,mcnt)
  constant=n_elements(hpos) eq 1
  nmaps=max(hpos)-1
  case 1 of 
    mcnt gt 0: cadence=-1 ; unknown
    max(hpos) eq 1: cadence=0
    else: cadence=nmaps/float(dt)
  endcase

endif else begin 
  box_message,'Strange scan??'
  cadence=-999
  file_append,'badsotsp.dat',l1dir
endelse

;  get scanID and set up directories
now=anytim(reltime(/now),/ccsds) 
scanid=(ssw_strsplit(l1dir,'/',/tail))(0)
sothttp='https://sot.lmsal.com/data/sot/'
root=ssw_strsplit(l1dir,'sot',/tail)
url_parent=sothttp+root+'/'

; populate structure (top level)
retval.instrume='SOTSP'
retval.eventid='VOEvent_ObsSP'+t0 + '.xml'
retval.search_start=t0
retval.search_stop=t1
retval.prog_start=t0
retval.prog_stop=t1
retval.annotation='SOTSP Scanid: '+ scanid
retval.creation_time=now
retval.url_parent=url_parent

; populate sub-structure (one structure for each Level 1.5 quantity)
retval.movie_info.fovx=(index.naxis1*index.cdelt1)/(nmaps>1) 
retval.movie_info.fovy=index.naxis2*index.cdelt2

retval.movie_info.mean_exptime=index.exptime
ctype=ssw_strsplit(index.cunit1+',',',',/head)
retval.movie_info.umode='SP IQUV 6302A '+ctype
retval.movie_info.wave='6302A '+ctype
retval.movie_info.wavelnth='6302A '+ctype
progno=gt_tagval(cat,/prog_no,missing=99)
retval.movie_info.prog_no=progno(0) ; assumption: constant for all "this" mode
retval.movie_info.obsdir='SP3D'
retval.movie_info.start_time=t0
retval.movie_info.stop_time=t1
retval.movie_info.mstart_time=t0
retval.movie_info.mstart_time=t0
retval.movie_info.nmatches=n_elements(cat)
retval.movie_info.nss=n_elements(cat)
retval.movie_info.date_obs=t0
retval.movie_info.xcen=index.xcen
retval.movie_info.ycen=index.ycen
retval.movie_info.waveid=11 ; consist w/FG 6302
retval.movie_info.cadence_mode=cadence
retval.movie_info.cadence_movie=cadence
retval.movie_info.movie_frames=nmaps
tn=tag_names(retval.movie_info)
ss=where(strpos(tn,'URL_') eq 0,ucnt)
for i=0,ucnt-1 do retval.movie_info.(ss(i))=''
gpre=strmid(strlowcase(ctype),0,4) 
gpre=gpre +  (['','s'])(gpre eq 'tran') + (['','c'])(gpre eq 'velo') ;??
urlparent=url_parent(0)
retval.movie_info.url_mparent=urlparent
retval.movie_info.url_mthumb=urlparent+gpre+'_thumb.png'
retval.movie_info.url_thumb=urlparent+gpre+'_thumb.png'
retval.movie_info.url_micon=concat_dir(urlparent,gpre+'_thumb.png')
retval.movie_info.url_context=urlparent+'cont_thumb.png'
retval.movie_info.url_context_thumb=urlparent+'clt_micon.png'
cfiles=file_search(l1dir,'*context*')

;  create context images
if keyword_set(context_redo) and cfiles[0] ne '' then begin
  ssw_file_delete,cfiles
  cfiles=file_search(l1dir,'*context*')
endif
mname=(ssw_strsplit((ssw_strsplit(fits,'/',/tail))(1),'.',/head))(0)
if n_elements(cfiles) lt 2 then begin
  oindex=index(1)
  sdata=bytscl(data(*,*,1) > (-100) < 100)
  defsiz=[300,1024,120]
  if n_elements(size_context) eq 0 then size_context=defsiz
  if n_elements(fov_context) eq 0 then $
    fov_context=[30,15,10] ; deffov
  cnames=mname+'_context_'+string(defsiz,format='(i4.4)')+'.gif'
  cfiles=concat_dir(l1dir(0),cnames)
  ssw_file_delete,concat_dir(l1dir,cnames)
  ct2rgb,0,rr,gg,bb,gamma=.8
  amatch=''
  eit_l1synop=keyword_set(eit_l1synop) or ssw_deltat(oindex(0),ref='1-oct-2006') lt 0
  aia=ssw_deltat(oindex(0),ref='1-jun-2010') gt 0
  mdi=1-aia
  merge=0
 
  if n_elements(fwave) eq 0 then fwave='193'
  for ci=0,1 do begin 
    cimg=hinode_fov_context(oindex,sdata,margin=.05*(ci eq 1),charsize=.7,$
      oplotnar=(ci eq 1), fov=fov_context(ci),xsize=size_context(ci), $
      r=rr,g=gg,b=bb, offset=50,/limb,grid=([15,5])(ci gt 0) , $
      eit_l1synop=eit_l1synop, aia=aia, fwave='193', mdi=mdi,  $
      /border, $
      debug=debug, gcolor=120,/goes,extremes=nomerge,all_fov=amatch, $
      composite=([2,3])(merge))
    if n_elements(cimg) eq 1 then box_message,'bad context??' else $
      write_gif,cfiles(ci),byte(cimg),rr,gg,bb 
  endfor
  if get_logenv('check_context') ne '' then stop,'cimg,aia,eit_l1synop'
endif
fnames=ssw_strsplit(cfiles,'/',/tail)
retval.movie_info.url_context_thumb=(url_parent+fnames(0))(0)
retval.movie_info.url_context=(url_parent+fnames(1))(0)
retval.movie_info.url_javascript=urlparent
retval.movie_info.url_mpeg=urlparent
retval.movie_info.url_gifanim=urlparent

;  save structure as a geny file
savegenx,retval,file=concat_dir(l1dir,scanid+'.geny'),/over

;  create XML
if keyword_set(ingest) then begin 

  ;  get base XML
  if debug then stop,'retval.movie_info'
  if n_elements(outdir) eq 0 then outdir=curdir()
  mk_voe_obs, retval,/write, outdir=outdir, /utility, buff=xmltext

  ;  add new tags at end of <What> section
  endwhat=strwhere(xmltext,'*</What>*')
  lev1files=file_search(str_replace(l1dir,'level1d','level1hao'),count=nlev1files,'*fits')
  lev1completionratio=(float(nlev1files)*index[0].scn_sum)/(float(index[0].nslitpos))
  newtags=!null
  newtags=[newtags,'        <lmsal:SCAN_ID>'+scanid+'</lmsal:SCAN_ID>']
  newtags=[newtags,'        <lmsal:PROG_VER>'+strtrim(index[0].prog_ver,2)+'</lmsal:PROG_VER>']
  newtags=[newtags,'        <lmsal:SEQN_VER>'+strtrim(index[0].seqn_ver,2)+'</lmsal:SEQN_VER>']
  newtags=[newtags,'        <lmsal:PARM_VER>'+strtrim(index[0].parm_ver,2)+'</lmsal:PARM_VER>']
  newtags=[newtags,'        <lmsal:PROG_NO>'+strtrim(index[0].prog_no,2)+'</lmsal:PROG_NO>']
  newtags=[newtags,'        <lmsal:SEQN_NO>'+strtrim(index[0].seqn_no,2)+'</lmsal:SEQN_NO>']
  newtags=[newtags,'        <lmsal:NSLITPOS>'+strtrim(index[0].nslitpos,2)+'</lmsal:NSLITPOS>']
  newtags=[newtags,'        <lmsal:SPNINT>'+strtrim(index[0].spnint,2)+'</lmsal:SPNINT>']
  newtags=[newtags,'        <lmsal:NUM_SIDE>'+strtrim(index[0].num_side,2)+'</lmsal:NUM_SIDE>']
  newtags=[newtags,'        <lmsal:SCN_STEP>'+strtrim(index[0].scn_step,2)+'</lmsal:SCN_STEP>']
  newtags=[newtags,'        <lmsal:SCN_RPT>'+strtrim(index[0].scn_rpt,2)+'</lmsal:SCN_RPT>']
  newtags=[newtags,'        <lmsal:SCN_SUM>'+strtrim(index[0].scn_sum,2)+'</lmsal:SCN_SUM>']
  newtags=[newtags,'        <lmsal:WEDGE>'+strtrim(index[0].wedge,2)+'</lmsal:WEDGE>']
  newtags=[newtags,'        <lmsal:FOCUS>'+strtrim(index[0].focus,2)+'</lmsal:FOCUS>']
  newtags=[newtags,'        <lmsal:NLEV1FILES>'+strtrim(nlev1files,2)+'</lmsal:NLEV1FILES>']
  newtags=[newtags,'        <lmsal:LEV1COMPLETIONRATIO>'+strtrim(lev1completionratio,2)+'</lmsal:LEV1COMPLETIONRATIO>']
  newtags=[newtags,'']
  newtags=[newtags,xmltext[endwhat]]
  xmlnew=strarrinsert(xmltext,newtags,xmltext[endwhat],/deldelim)

  ;  rewrite XML
  outfil_voevent = concat_dir(outdir,retval.eventid)
  file_append,outfil_voevent,xmlnew, /newfile  ;  same command in mk_voe_obs.pro

  ;  ingest
  ssw_coverage_ingest,concat_dir(outdir,retval.eventid)
endif

return, retval
end

