



pro trace_find_mosaic, start_time, stop_time, index, data, count, debug=debug, $
	percent=percent, _extra=_extra, wave=wave,  nopatch=nopatch, $
	setnumber=setnumber, name_index=name_index, imgperset=imgperset, $
	number_sets=number_sets, set_only=set_only, set_selected=set_selected
;
;   Name: trace_find_mosaic 
;
;   Purpose: return mosaics sets between time0 and time1
;
;   Input Parameters:
;      start_time - start time of interest
;      stop_time  - stop time of interest
;  
;   Output Parameters:
;      index - the index structures  
;      data  - (optional output) the 2D or 3D data array
;
;   Keyword Parameters:
;      percent     - quality cutoff (default=100%)
;      wave        - wavelengh
;      /WXXX       - optionally define wavelenths like: /w171, /w195, /w1216
;      nopatch     - if set, dont fill missing components from neighbor sets
;      setnumber   - input - desired set number if multiple sets/trange
;      set_only    - if set, only define NUMBER_SETS (output) and return
;                    [used in caller for multiple set processing, for examp]
;      number_sets  - (OUTPUT) - return number sets within time range
;      set_selected - (OUTPUT) - which set is selected
;                     => 0 if only one avail
;                     => same as SETNUMBER if user supplied
;                     => else: default is the 'best set' within time range
;      name_index   - (OUTPUT) - reference structure
;                     [for uniq names & rotation reference after patching]
;      imgperset    - (OUTPUT) number of components per set prior to patching
;  
;   Calling Examples:
;      IDL> trace_find_mosaic, t0, t1, index, data, wave='171' ; find 'best'
;      IDL> trace_find_mosaic, t0, t1, index, data, wave='171', $
;             number_sets=number_sets, imgperset=ips,/set_only ; get info
;
;   History:
;      1-December-1998 - break out mosaic logic from last_trace
;      8-November-1999 - improve logic and include 'smallmosaics'
;                        increase output information for caller routines
;                        Add common 'trace_find_mosaic_blk' for efficiency
;   Calls:
;       trace_cat, trace_cat2data, read_trace, trace_prep, data_chk, $
;       deriv_arr, anytim, last_nelem, strsplit...
;
;   Method: use TRACE catalog, simple filters and catalog->data mapping SW  
;-  
; common used to avoid rereads of catalog and index records
common trace_find_mosaic_blk, last_t0, last_t1, last_catalog, last_ss, last_index

if n_elements(last_t0) eq 0 then begin 
   last_t0=''                             ; 1st?, init to force read
   last_t1=''
   last_ss= -2      
endif

debug=keyword_set(debug)
; ----------------- wavelength selection --------------
case 1 of
  keyword_set(wave): iwave=wave
  data_chk(_extra,/struct): begin
    tags=(tag_names(_extra))(0)
    if strmid(tags,0,1) eq 'W' then iwave=fix(strmid(tags,1,5)) else iwave=171
  endcase
  else: iwave=171
endcase
swave=strtrim(iwave,2)

;-----------------------------------------------------------
if not keyword_set(percent) then percent=100         ; default=perfect

if keyword_set(start_time) then begin
   if not keyword_set(stop_time) then stop_time=timegrid(start_time,hour=48,/string)
   t0=anytim(start_time,/ecs)                      ; known conversion
   t1=anytim(stop_time,/ecs)                       ; ditto
   oldcat=1   
   if t0 ne last_t0 or t1 ne last_t1 then begin 
      trace_cat,start_time,stop_time,catalog       ; read/re-read catalog
      last_t0=t0    
      last_t1=t1
      oldcat=0
      last_catalog=catalog
    endif else catalog=last_catalog                 ; else, use common
endif else trace_cat, /last36,catalog       ; default is newest

; apply filter for known mosaic OBSERVING PROGRAMS
obsmap=intarr(n_elements(catalog))
moslist=str2arr('.fulldisk.,.fdm.,uvfull,smallmosaic')  ; mosaic observing program names
for i=0,n_elements(moslist)-1 do $
       obsmap=obsmap OR  (strpos(catalog.obs_prog, moslist(i)) ne -1)

; --------------- the filter -----------------------------
ss=where(       obsmap                           and    $ ; obs-prog
	        catalog.wave_len eq swave        and    $ ; wavelength
                catalog.percentd ge percent      and    $ ; quality
                ( (catalog.naxis1 eq 1024 and catalog.naxis2 eq 1024) or $
                  (catalog.naxis1 eq 512 and catalog.naxis2 eq 512 )) , icnt)
;-----------------------------------------------------------
if icnt le 1 then begin
    box_message,'No images match your mosaic criteria'
    return
endif    
;-----------------------------------------------------------
sss=0
if icnt gt 1 then sss=sort_index(catalog(ss),/uniq,/ss)
ss=ss(sss)

;-----------------------------------------------------------
set_selected=-1
ss0=0
pos=0

oldcat = oldcat and (n_elements(ss) eq n_elements(last_ss) and $
		     total(ss ne last_ss) gt 0)

if not oldcat then begin 
   trace_cat2data, catalog(ss), index    ; use named position
   last_ss=ss
   last_index=index   
endif else index=last_index
  
pos=str2number(strsplit(index.trg_nam,'.',/tail))
hpos=histogram(pos,min=0)
pbest=(where(hpos eq max(hpos)))(0)
flgs=intarr(hpos(pbest),n_elements(hpos))

if max(pos) eq 0 then  nimg=cutoff(0)>0<26   else begin
        cutoff=where(deriv_arr(pos)lt 0)              ; uniq mosaic sets
        ncut=n_elements(cutoff)
        mstart=[0,cutoff+1]                           ; 1st component
        mstop=[cutoff,n_elements(pos)-1]              ; last component
        imgperset=mstop-mstart+1                      ; components/set

;       choose which mosaic set to consider
        case 1 of
           ncut eq 1: set=(where(mstop ne -1))(0) >0                                ; only 1
	   n_elements(setnumber) gt 0: set=setnumber<ncut  ; user supplied
	   else: begin
             box_message,'Auto-set selection'
             set=last_nelem(where(imgperset eq max(imgperset)))  ; def: best
           endcase
        endcase	   
        sss=ss(mstart(set):mstop(set))           ; subscripts of this set
	nimg=n_elements(sss)                     ; number components
endelse
number_sets=ncut                                 ; return total sets
set_selected=set                                 ; return which set
if keyword_set(set_only) then return             ; <<< EARLY EXIT!

if max(pos) gt 0 then begin                        
  ssx=tim2dset(index,catalog(sss))                         ; remap
  name_index=index(ssx(0))                                 ; uniq mosiac names
  ncomp=n_elements(ssx)
  ideal= ([ ([24,42])(max(pos) gt 24), max(pos)])(max(pos) lt 10)
  box_message,'IDEAL>> ' + strtrim(ideal,2)
  posits=indgen(ideal)+1
  case 1 of
     n_elements(ssx) ge ideal: box_message,' All components present'
     keyword_set(nopatch): box_message,'/NOPATCH set, not patching...'
     else: begin
        box_message,['Missing ' + strtrim(ideal-ncomp,2) + ' components']     
        required=rem_elem(posits,pos(ssx))
       
        for i=0,n_elements(required)-1 do begin
	   box_message,'Trying to patch position# ' + strtrim(posits(required(i)),2)
           css=where(pos eq posits(required(i)),csscnt)
           if csscnt gt 0 then begin
             box_message,'Found ' + strtrim(csscnt,2) + ' corresponding components, patching...'
;            ----- highest quality first - then closest in time -----
             csx=where(index(css).percentd eq max(index(css).percentd)) 
             csxss=tim2dset(index(css(csx)),index(ssx(0)))
             sss=[sss,ss(css(csx(csxss)))]
           endif else box_message,'No corresponding components available
         endfor
     endcase       
  endcase
endif  

if n_elements(sss) gt 1 then sss=sss(sort(sss))
if debug then stop,'sss,ssx,pos check...'

;-----------------------------------------------------------
trace_cat2data,catalog(last_nelem(sss,ideal)),files,dset,/filedset  ; catalog->data mapping
read_trace, files, dset, index, data, /all,nodata=n_params() le 3  ; read the data

box_message,['Read image'+(['','s'])(n_elements(index) gt 0)+':', $
   get_infox(index,/fmt_tim,'wave_len,naxis1,naxis2,obs_prog',format='a4,i5,i5,a')]	     
;-----------------------------------------------------------

return
end
