; Make selection doc files and filtered images for each reference view
 ;
 ; SOURCE:   spider/docs/techs/recon/Procs/sel-filt-byview.spi
 ;
 ; PURPOSE:  Make selection doc files for reference views
 ;
 ; USAGE:    clean ; ./spider spi/dat @sel-filt-byview
 ; OPTIONS:  clean ; ./spider spi/dat @sel-filt-byview 0 numProcs=4 skipCombine=1 shrink=2 saveAvg=1

 ; REQUIRES: spider/docs/techs/recon/Procs/verify-settings.spi
 ;           spider/docs/techs/recon/Procs/align-combine.spi
 ;
 ; FROM spider/docs/techs/recon/Procs/:
 
 ; ----------------------- Parameters -----------------------

 [numCPUs]       = 0     ; Number of processors to use (0 == all, can override from command line)
 [combineYN]     = 1     ; Combine alignment files? (0 == no, can override from command line)

 [filter-type]   = 7     ; Filter type for optional filtered images (7 == Butterworth)
 [filt-param1]   = 30.0  ; Pass-band, Angstroms (assuming Butterworth)
 [filt-param2]   = 20.0  ; Stop-band, Angstroms (assuming Butterworth)
 [reduction]     = 5     ; Size factor (integer) for optional filtered images (can override from command line)

 [saveAvgYN]     = 1     ; Flag to save unfiltered view-average (1 == save, can override from command line)
 [saveFiltYN]    = 1     ; Flag to save filtered images         (1 == save)

 [last-view]     = 0     ; Last reference-view to filter  (0 == all)
 [view-progress] = 1     ; Prints progress message every Nth reference view
 
 ; INPUT FILES: ([win_dir] denotes input directory, 
 ;               [rec_dir] denotes reconstruction output directory and '***' denotes group)
 ;   [params]           = '../params'                     Parameter doc file         (one)
 ;   [sel_group]        [win_dir]/sel_group               Group selection doc file      (one)
 ;   [sel_part]         [win_dir]/sel_part_***            Particle selection doc file   (one/group)
 ;   [global2group_lut] [win_dir]/global2group            Particle-number lookup table  (one)
 ;   [align_doc]        [rec_dir]/align_01_***            Particle alignment doc files  (one/group)
 ;   [ref_view_list]    [rec_dir]/sel_proj                List of reference views    (one)
 ;   [aligned_images]   [rec_dir]/dala_01_***             Aligned-images stack       (one/group)
 ;
 ; OUTPUTS:   (Where ### denotes projection view)
 ;   [temp_view_sel]      views/tmpsel###                 Temporary by-view particle list (one/view)
 ;   [view_list]          views/prj###/sel_part_byv       By-view particle list         (one/view)
 ;   [sorted_particles]   views/prj###/sel_part_byv_sort  Particle list sorted by CCROT (one/view)
 ;   [parts_vsview]       views/parts_vsview_all          List of particles per view    (one)
 ;   [combined_align_doc] align_01_all                    Combined alignment doc file   (one)
 ;   [sd_vsview]          sd_vsview                       View average summary doc file           (one)
 ;   [filtered_stack]     views/prj###/stkfilt            Filtered view average stacks            (one/view)
 ;   [total_view_avg]     views/prj###]/allavg            OPTIONAL full-sized view average stacks (one/view)
 ;
 ; ----------- END BATCH HEADER ----------------

; Set common filenames & parameters
@verify-settings

; Override with optional command-line values
IF ( [shrink]  .GT. 1)   [reduction] = [shrink]
IF ( [saveAvg] .GE. 0.5) [saveAvgYN] = [saveAvg]

; Check if we need to combine the alignment parameters
IF ( [skipCombine] .EQ. 1) THEN
  IQ FI [combinedExistsYN]
    [combined_align_doc]
    
  IF ( [combinedExistsYN] .EQ. 0) THEN
    SYS
      echo " Can't find [combined_align_doc].$DATEXT, will generate it..." ; echo

    [combineYN] = 1
    
  ELSE
    [combineYN] = 0
  ENDIF
ENDIF

IF ( [saveFiltYN]+[saveAvgYN] == 0 ) THEN
    SYS
    echo " WARNING: Neither unfiltered nor filtered average requested -- Continuing..." ; echo
ENDIF


; Temporary files
[temp_sel_incore]      = 'tmpselview'
[fullsize_mask]        = '_6'
[temp_mirrored_incore] = '_5'
[temp_filtered_incore] = '_4'
[temp_filtered_stack]  = '_2'
[temp_fullsize_stack]  = '_1'
[temp_variance_incore] = '_3'

MD
  RESULTS OFF

SYS                                 ; Make sure output dir. present
  mkdir -p [view_dir] 

  
; Combine alignment parameters, if needed
@align-combine([totParts],[numViews])
  [combineYN]                       ; If not combining, will simply return the number of particles and views
  
  
DE                                  ; So can not append to any pre-existing file
  [parts_vsview]                    ; # particles / view summary file   (removed)

; Label summary file
SD /   #-OF-PARTS 
  [parts_vsview]                    ; # particles / view summary file   (output)

; Initialize variables
[max-imgs]       = -1
[min-imgs]       = 9999999
[prevGrp]        = 0

; Get parameters
UD 5, [pixel-size]
  [params]
UD 17, [windowSize]
  [params]
UD E

[reduced-size] = [windowSize]/[reduction]
[mask-radius]  = INT([reduced-size]/2)

DE
[sd_vsview]

IF ( [saveAvgYN]  > 0 ) THEN
    DE
      [total_view_avg]@
    
    ; Make circular mask
    MO
      [fullsize_mask]              ; OUTPUT
      [windowSize],[windowSize]    ; Image dimensions
      C                            ; Circle
      [mask-radius]                ; Mask radius

    SD /       VIEWNUM      PARTICLES        SD_VAR
      [sd_vsview]             ; File         (output)
ELSE
    SD /       VIEWNUM      PARTICLES      
      [sd_vsview]             ; File         (output)
ENDIF

; Change filter radii to reciprocal pixels
[filt-param1] = [pixel-size]/[filt-param1]  ; Pass-band if Butterworth
[filt-param2] = [pixel-size]/[filt-param2]  ; Stop-band

IF ( [last-view] == 0 ) THEN
    UD N [last-view]
      [ref_view_list]
    
    [numViews] = [last-view]
ENDIF

; If #CPUs passed from command line, then override value in header
IF ( [saveFiltYN] .GE. 0.5) THEN   ; Only need multiple CPUs if filtering images
  IF ( [numProcs] > 0 ) THEN
    MD                          
      SET MP                       ; Set OMP processors from command-line value
      [numProcs]
  ELSE
    MD                          
      SET MP                       ; Set OMP processors from header value
      [numCPUs]
  ENDIF
ENDIF

; Loop through views
DO LB61 [view] = 1,[numViews]
  ; Get #particles
  UD N [numViewParts]
    [temp_view_sel][view]
  
  IF ([numViewParts] .EQ. 0) GOTO LB63

  SYS
    mkdir -p [prj_dir][view]

  DE                         ; Delete
    [view_list][view]        ; Particle selection for view doc file (output)

  DE                         ; Delete
    [sorted_particles][view] ; Particle selection for view doc file (output)
  SD /           NUM       GLO_NUM      GRP_WIN        CCROT      MIRROR_FLAG    GRP_NUM        VIEW        MIC
    [sorted_particles][view] ; Sorted particle selection for view doc file (output)
  SD E
    [sorted_particles][view] ; Sorted particle selection for view doc file (closed)
                      
  SD IC NEW
    [temp_sel_incore]
    8,[numViewParts]   ; #registers, #particles

  SYS
    mkdir -p [prj_dir][view]
      
  ; Initialize stacks
  IF ( [saveFiltYN]  > 0 ) THEN    
      DE
        [temp_filtered_stack]         ; Stack     (output)
      
      MS
        [temp_filtered_stack]@        ; Stack     (output)
        [reduced-size],[reduced-size] ; Dimensions
        [numViewParts]               ; Max image allowed
  ENDIF
  
  IF ( [saveAvgYN]  > 0 ) THEN
      DE
        [temp_fullsize_stack]@        ; Stack     (removed)

      MS
        [temp_fullsize_stack]@        ; Stack     (output)
        [windowSize],[windowSize]     ; Dimensions
        [numViewParts]                ; Max image allowed
  ENDIF

  DE
  [filtered_stack][view]

  ; Loop through particles
  DO LB62 [pkey] = 1,[numViewParts]

      ; Read global#
      UD IC [pkey], [gloNum] 
        [temp_view_sel][view]

      ; Get group info
      UD IC [gloNum], [grpWin],[micWin],[grp],[mic]
        [global2group_lut]

      ; Close docs if new group
      IF ([grp] .NE. [prevGrp]) THEN
          UD ICE
            [align_doc][prevGrp]

          [prevGrp] = [grp]
;        ELSE
;            UD IC [grpWin], [r1],[r2],[r3],[ref],[exp],[r6],[r7],[r8],[r9],[r10],[r11],[ccrot],[r13],[r14],[mir]
;              [align_doc][grp]            ; Particle alignment doc files  (input)
      ENDIF

      UD IC [grpWin], [r1],[r2],[r3],[ref],[exp],[r6],[r7],[r8],[r9],[r10],[r11],[ccrot],[r13],[r14],[mir]
        [align_doc][grp]            ; Particle alignment doc files  (input)
      
      SD IC [pkey], [pkey],[gloNum],[grpWin],[ccrot],[mir],[grp],[view],[mic]
        [temp_sel_incore]   ; WAS [view_list][view]

      ; Mirror, if necessary
      IF ( [mir] < 0 ) THEN
          MR
            [aligned_images][grp][grpWin] ; Image          (input)
            [temp_mirrored_incore]               ; Mirrored image (output)
            Y                                    ; Mirror around y-axis
      ELSE
          CP
            [aligned_images][grp][grpWin]
            [temp_mirrored_incore]
      ENDIF

      ; Copy to full-sized stack, if necessary
      IF ( [saveAvgYN]  > 0 ) THEN
          CP
            [temp_mirrored_incore]              ; File         (input)
            [temp_fullsize_stack]@{*****[pkey]} ; (output)
      ENDIF

      ; Filter, if necessary
      IF ( [saveFiltYN]  > 0 ) THEN
          ; If Butterworth filter
          IF ( [filter-type] == 7 ) THEN
              FQ NP
                [temp_mirrored_incore]       ; File         (input)
                [temp_filtered_incore]       ; File         (output)
                [filter-type]                ; Filter type
                [filt-param1],[filt-param2]  ; passband, stopband
          ENDIF

          ; If Fermi filter
          IF ( [filter-type] == 5) THEN
              FQ NP
                [temp_mirrored_incore]       ; File         (input)
                [temp_filtered_incore]       ; File         (output)
                [filter-type]                ; Filter type = Fermi
                [filt-param1]                ; Filter radius
                [filt-param2]                ; Temperature cutoff
          ENDIF

          ; If Gaussian or top-hat filter
          IF  ( [filter-type] <= 3 ) THEN
              FQ NP
                [temp_mirrored_incore]       ; File         (input)
                [temp_filtered_incore]       ; File         (output)
                [filter-type]                ; Filter type = top hat, Gaussian
                [filt-param1]                ; Filter radius
          ENDIF

          ; Shrink, if necessary
          IF ( [reduction]  > 1 ) THEN
              DC S
                [temp_filtered_incore]      ; File          (input)
                [temp_filtered_stack]@{*****[pkey]}
                [reduction],[reduction]     ; Reduction in X,Y
          ELSE
              CP
                [temp_filtered_incore]      ; File            (input)
                [temp_filtered_stack]@{*****[pkey]}   ;  (output)
          ENDIF
      ENDIF                               ; Filter IF-THEN
      
  LB62
  ; End particle-loop

  ; Clean up
  UD ICE
    [temp_view_sel][view]
  SD IC COPY
    [temp_sel_incore]
    [view_list][view]
  SD ICE
    [temp_sel_incore]
  SD /           NUM       GLO_NUM      GRP_WIN        CCROT      MIRROR_FLAG    GRP_NUM        VIEW        MIC
    [view_list][view]        ; Particle selection for view doc file (output)
  SD E
    [view_list][view]

  IF ( [saveAvgYN]  > 0 ) THEN
      AS R
        [temp_fullsize_stack]@*****     ; File          (input)
        1-[numViewParts]                ; Image range
        A                               ; All particles
        [total_view_avg]@{***[view]}    ; Average file  (output)
        [temp_variance_incore]          ; variance  (output, not saved)

      ; Get standard deviation of the variance
      FS M [min],[max],[avg],[sd-var]
        [temp_variance_incore]          ; Variance
        [fullsize_mask]
  ELSE
      [sd-var] = 1                      ; Dummy variable
  ENDIF

  CP
    [temp_filtered_stack]@              ; File         (input)
    [filtered_stack][view]@             ; File         (output)

  DE
    [temp_filtered_stack]@

  ; Write info to document
  SD [view], [view],[numViewParts],[sd-var]
    [sd_vsview]                     ; File         (output)

  LB63  ; Skip here if no particles in view
  
  DE
    [temp_view_sel][view]

  ; Update min, max
  IF ( [numViewParts] > [max-imgs] ) [max-imgs] = [numViewParts]
  IF ( [numViewParts] < [min-imgs] ) [min-imgs] = [numViewParts]

  ; Check if particle-list exists
  IQ FI [list-exists]
    [view_list][view]              ; Particle selection for view doc file (input)

  ; Skip if particle-list does not exist
  IF ( [list-exists] == 1) THEN
      ; Sort by CC
      DOC SORT A                     ; Sort doc file & append to existing lable
        [view_list][view]            ; Particle selection for view doc file  (input)
        [sorted_particles][view]     ; Particle selection for view doc file  (output)
        -4                           ; Column # to sort by CCROT, Reverse order
        Y                            ; Renumber the keys
  ENDIF

  ; Write to summary
  SD [view], [numViewParts]
    [parts_vsview]               ; # particles / view summary file   (output)

  SYS
    echo " View: {%I3%[view]}   Particles: {%I6%[numViewParts]}"

LB61
; End view-loop

; Clean up
UD ICE
  [global2group_lut]
UD ICE
  [align_doc][grp]
SD /   #VIEWS  TOTPARTS       MAXIMGS       MINIMGS
  [parts_vsview]          ; # particles / view summary file   (output)
[dummy] = -[numViews]
SD [dummy], [totParts],[max-imgs],[min-imgs]
  [parts_vsview]          ; # particles / view summary file   (output)
SD E
  [parts_vsview]          ; # particles / view summary file   (closed)
SD E
  [sd_vsview]                            ; File        (closed)

SYS
  echo ; echo -n " Done, separated: {%I0%[totParts]} particles    "; date

EN

; Modified 2016-10-19
;    2016-05-31 (trs) -- split off combine-align.spi
;    2016-04-27 (trs) -- combined select-byview and avg-filt-byview
;    2015-12-03 (trs) -- rewrote to use in-core doc files and write out combined alignment doc
;    2013-10-23 (agl) -- new file names, modernized syntax & cosmetic
;    2012-04-11 (trs) -- prints min & max populated views in HOW_MANY file
;    2012-04-06 (trs) -- adapted from selectbyviewall.spi
;    2011-11-02 (trs) -- added output: combined HOW_MANY file
;    2011-10-21 (trs) -- do not need reversedoc_7col anymore (needs SPIDER v18.19+)
;    2011-10-21 (trs) -- updated to named registers
;    2009-04-21 (trs) -- added version of select/sel sorted by CCROT
;    2009-02-23 (trs) -- added view# to select/sel output
;    2008-01-30 (trs) -- last angle in refangles not necessarily redundant
;    2007-08-07 (trs) -- reflects changes to input doc file sel_part
;    2007-06-06 (trs) -- bug fix cleaning out pre-existing files, format change
;    2007-05-30 (trs) -- reflects changes to input doc file sel_part
;    2007-03-27 (trs) -- reflects changes to input doc file sel_part
;    2007-02-20 (trs & djt) -- bug fix: group directories were not correctly created

;