;+
;
; Project   : s3drs and Pixon reconstruction software
;                   
; Name      : p_process_filelist
;               
; Purpose   : part of the s3drs GUI
;               
; Explanation: (part of the testing and legacy code, not documented herein)
;               
; Use       : 
;    
; Inputs    : 
;               
; Outputs   : 

; Keywords  :
;               
; Common    : 
;               
; Restrictions: none
;               
; Side effects: 
;               
; Category    : 
;               
; Prev. Hist. : (see CVS logs)
;
; Written     : Sandy Antunes, NRC, 2007-2009
;               
;-            
; Expects FITS files, either Level 0.5 or Level 1.0
;
; given a filelist and initial pxwrapper structure, gets all
; our requisite data, noise and masks and creates our Pixon
; structures in 'pxwrapper' and Pixon object in 'oPixon'
;
; 'noisemodel' can be a single item or an array, but we cast it
; into an array either way and return it as its new array form.
;
; 'N' is the sim resolution and thus the desired final array size
; (rebinned losslessly) desired.
;
; See 'p_doc.html' for more details on each step.
;
; Choices for noisemodel are:
;   0: no noise
;   1: use secchi_prep on Level0.5 sigmaDN (best method)
;   2: use fractional error of Level0.5 on Level1.0 data
;   3: fake secchi_prep on Level0.5 data
;   4: use fractional error on Level1.0 data (method 2 but for L1.0)
;   5: fake secchi_prep on fake unprepped Level1.0 data (method 3 but for L1.0)
;

PRO p_process_filelist,N,filelist,pxwrapper,oPixon,noisemodel

    if (n_elements(N) eq 0 or n_elements(filelist) eq 0) then $
      stop,'p_process_filelist requires N and a filelist of FITS names'
   
    nfiles=n_elements(filelist)

    if (n_elements(pxwrapper) eq 0) then $
      prep_3drv,pxwrapper,views=nfiles,N=N

;; look up which noise model to use

    ; default noise model, if none given, is from pxwrapper
    if (n_elements(noisemodel) eq 0) then begin
        noisemodel=pxwrapper.sp.noisemod
    end
    ; alternately, if given a single model choice, forces to an array
    if (n_elements(noisemodel) ne nfiles) then begin
        noisemodel=make_array(nfiles,/int,value=noisemodel)
    end


    ; create our data storage placeholders
;    datum=make_array(N,N,nfiles,/double,value=1.0)
;    noise=datum
;    masks=datum
    datum=ptrarr(nfiles)
    noise=ptrarr(nfiles)
    masks=ptrarr(nfiles)

    ; get all headers to determine mission and file processing level
    mreadfits,filelist[iele],hdrs,/nodata

    for iele=0,nfiles-1 do begin

        bpp = hdrs[iele].bitpix

        if (bpp eq 16) then begin

            ; 16 bits per pixel indicates an integer, likely Level 0.5 data

            ; first, get 05 data for noise calculation
            mreadfits,filelist[iele],hdr05,data05

            ; then run secchi_prep on it to get the data in 1.0 form
            secchi_prep,filelist[iele],hdr10,data10

            ; get binned data, masks, and structures needed
            p_ingest_fits,filelist[iele],datum[iele],srjr,masks[iele], $
              pxwrapper=pxwrapper,iele=iele,indata=data10,inhdr=hdr10,N=N

            noise[iele]=p_noisewrapper(noisemodel[iele],data05,N=N, $
                                           hdr=hdr05,data10=data10,/pointer)

        end else begin

            ; likely a Level 1.0 file, so just pass the filename to ingest

            ; get binned data, masks, and structures needed
            p_ingest_fits,filelist[iele],datum[iele],srjr,masks[iele],$
              pxwrapper=pxwrapper,iele=iele,N=N

            ; only models 0, 4, 5 work for L1 (same as 0,2,3 but for L1)
            ; so map 0->0, 1->4, 2->4, 3->5, 4->4, 5->5
            if (noisemodel[iele] ne 0 and noisemodel[iele] le 3) then begin
                if (noisemodel[iele] eq 3) then noisemodel[iele] = 5 else $
                  noisemodel[iele]=4
            end

            ; also get raw 10 data for noise calculation
            mreadfits,filelist[iele],hdr10,data10
            noise[iele]=p_noisewrapper(noisemodel[iele],data10,N=N,/pointer)

        end


        ; now that we have data and noise, rotate if necessary so
        ; all images are aligned to ecliptic north.
        if (srjr.align eq 'solar') then begin
            c=p_getk0(srjr)
            e=0.0-srjr.ecliptic
            *(datum[iele])=rot(*(datum[iele]),$
                            e,1.0,c[0],c[1],missing=0,/interp,/pivot)
            *(noise[iele])=rot(*(noise[iele]),$
                            e,1.0,c[0],c[1],missing=0,/interp,/pivot)
            *(masks[iele])=rot(*(masks[iele]),$
                            e,1.0,c[0],c[1],missing=0,/interp,/pivot)
            srjr.align='ecliptic'
        end

    endfor

    p_generate_pixon,'classic',pxwrapper,oPixon
    p_insert_data,pxwrapper,datum,oPixon,sigma=noise,mask=masks

  ; object is now prepped and loaded, ready to run Pixon!

END

; II) Initialize structures:
; 	run "prep_3drv,pxwrapper,views=n_elements(filelist),N=N"
; 
; (skipping 'tweak kernel' here)
; 
; IV) "p_process,filelist,pxwrapper,datum,masks,noise"
; 
;     i) create placeholders for data, noise, masks as N,N,nfiles arrays
; 
;     ii) Noise generation:
; 
; 	A) Have Level 0.5 data?
; 	   generate noise from 0.5 using noise methods 1, 2 or 3 (1 is best)
; 	C) Have only Level 1.0 data?
; 	   generate noise from 1.0 using noise methods 4 or 5 (4 is best)
; 
;     iii) Data check:
; 	A) Have Level 1.0 data?
; 		move to next step
; 	B) Have only Level 0.5 data?
; 		run secchi_prep on 0.5 to make level 1.0 data
; 
;     iv) Data ingest:
; 	run p_ingest_fits on level 1.0 data
; 
;     v) Structure updating:
; 	insert srjr from p_ingest_fits into pxwrapper.sr
; 	("p_update_struct,pxwrapper,'sr',srjr,iele")
; 
;     vi) Data collection:
; 	accumulate data, mask, noise sets
; 
;     vii) (repeat ii-vi for each additional data file)
; 
; V) Prepare Pixon object and insert data items:
; 	"p_generate_pixon,'classic',pxwrapper,oPixon'
; 	"p_insert_data,pxwrapper,data,oPixon,sigma=noise,mask=masks"
