; Extract a noise image
 ;
 ; SOURCE:  spider/docs/techs/recon1/Procs/make-noise-img.spi
 ;
 ; PURPOSE  Extract a series of particle-sized windows from a
 ;          micrograph, compare their standard deviations to obtain 
 ;          a noise image.
 ;
 ; An initial set of windows is sorted by their standard deviations.
 ; An area in the center of the micrograph is examined (the large window).
 ; From the 30 windows with lowest std devs, a second measurement is made
 ; of the local std. dev. of each quadrant of each window, which are then
 ; sorted by this second measure. 
 ; This set of images should be viewed in Web to select the final noise file.
 ; 
 ; Selects one and copies it to the output noise file
 ;
 ;
 ; USAGE:   clean ; spider spi/mrf @make-noise-img
 
 ; --------------- Registers ------------------------

 [viewYN]     = 2           ; Open viewer automatically? (1: final image, 2: all images)
 [micNum]     = -1          ; Micrograph from which to window noise image (-1: automatic)
 [micWinSize] = 2000        ; Size of large window (area to be examined)
 [cleanYN]    = 1           ; Delete temp doc files? (1 = delete, 0 = don't delete)

 ; ---------------- Input files -------------------

 [params]   = '../params'                           ; Parameter file 

 [mic]      = '../Micrographs/raw{****[micNum]}'    ; Raw micrograph
 
 [mic_list] = '../Power_Spectra/defocus'            ; Micrograph list (optional, needed if micrograph chosen automatically)
                                                    ; If a defocus doc file, will sort by 2nd column (defocus)

 ; --------------- Output files ------------------

 [noise]    = 'noise'                  ; Selected output noise window

 [ndir]     = 'tmpnoise'               ; Directory for noise images

 [output]   = '[ndir]/noi'             ; Series of output noise windows

 ; -------------- END BATCH HEADER --------------------------

 SYS
   mkdir -p [ndir] 

 ; Temporary files
 [docnoise]            = '[ndir]/docnoise'      ; Doc file of window statistics
 [docsort]             = '[ndir]/docsort'       ; Sorted doc file
 [docvar]              = '[ndir]/docvar'        ; Doc file of local variance
 [docvarsort]          = '[ndir]/docvarsort'    ; Doc file of sorted local variance
 [temp_defocus_sorted] = 'tmpdocdefocus-sort'   ; Sorted defocus doc (can use sel_micrograph too)
 [temp_noise_win]      = '_1'                   ; Windowed noise image
 [temp_mic_win]        = '_2'                   ; Windowed micrograph

 ; Delete the doc files if they already exist
 DE
   [docnoise]
 DE
   [docsort]
 DE
   [docvar]
 DE
   [docvarsort]

 UD 17,[sp_winsiz]     ; Get the window size
   [params]
   
 IF ([micNum] .LT. 1) THEN
   ; Determine micrograph# to use
   UD N x99,[ncols]
     [mic_list]
   
   IF ([ncols] .GT. 2) THEN
     [ncols] = 2
   ELSE
     [ncols] = 1
   ENDIF
   ; (Assuming 2nd column is defocus value, otherwise will sort by first column, assumed to be micrograph#)
   
   ; Sort defocus doc
   DOC SORT
     [mic_list]
     [temp_defocus_sorted]
     [ncols]                      ; Column# to sort
     Y                            ; Renumber?
     
   [one] = 1
   
   ; Get first micrograph # if not specified
   IF ( [micNum] <= 0 ) THEN
     UD [one], [micNum]
       [temp_defocus_sorted]
     UD E
    
     SYS
       echo ' Will pick noise reference from micrograph [mic]' ; echo
    
     DE
       [temp_defocus_sorted]
   ENDIF
 ENDIF

 [deci] = 1
; @convert-p([deci])
;   [params]            ; Parameter file
;   [raw]               ; Micrograph                  (input)
;   [mic]               ; SPIDER file                 (output)

 [lowest30sd]     = 30            ; Use the top (30) with smallest std_dev
 [percentOverlap] = 50            ; Percent overlap of the small windows

 ; ----------------------------------------------------------
 ; The large window is at the center of the input image.
 ; [micTopLeftX] =  X upper left corner of large window
 ; [micTopLeftY] =  Y upper left corner of large window

 FI H [micXDim],[micYDim]      ; Get file size
   [mic]              ; Micrograph                 (input)
   NX,NY

 IF ([micWinSize].GT.[micXDim]) [micWinSize] = [micXDim]
 IF ([micWinSize].GT.[micYDim]) [micWinSize] = [micYDim]

 [micTopLeftX] = ([micXDim] - [micWinSize]) / 2
 [micTopLeftY] = ([micYDim] - [micWinSize]) / 2
 IF ([micTopLeftX].LT.1) [micTopLeftX] = 1
 IF ([micTopLeftY].LT.1) [micTopLeftY] = 1

 ; ----------------------------------------------------------

 ; [winTopLeftX] = start x for each window 
 ; [winTopLeftY] = start y for each window

 [ratio] = 100 / [percentOverlap]
 [numWin]    = ([micWinSize]/[sp_winsiz]) * [ratio]    ; Number of windows in X and Y
 [numWin]    = [numWin] - 1
 [increment] = int([sp_winsiz] / [ratio])              ; Increment for start window coords

 [counter] = 1                                         ; A counter for incrementing keys

 ; If the doc files already exist, delete them
 DE
   [docnoise]
 DE
   [docsort]
 DE
   [docvar]
 DE
   [docvarsort]

 ; First Loop ------------------------------------------------

 DO [xkey] = 1,[numWin]      ; Y loop
   DO [ykey] = 1,[numWin]    ; X loop

      [winTopLeftX] = [micTopLeftX] + [increment] * ([ykey] - 1)    ; X UL corner of window
      [winTopLeftY] = [micTopLeftY] + [increment] * ([xkey] - 1)    ; Y UL corner of window

      WI
        [mic]
        [temp_noise_win]
        [sp_winsiz],[sp_winsiz]                                     ; Dimensions
        [winTopLeftX],[winTopLeftY]                                 ; Top left coords

      ; Get standard deviation
      FS [v71],[v72],[v73],[stdev]
        [temp_noise_win]

      SD [counter], [stdev], [winTopLeftX],[winTopLeftY]              ; Save key,std_dev,x,y
        [docnoise]

      [counter] = [counter] + 1

   ENDDO
 ENDDO

 ; -----------------------------------------------

 DOC SORT                      ; Sort docfile according to std_dev (column 1)
   [docnoise]
   [docsort]
   1 
   Y

 UD N, [numEntries]            ; Get the number of entries
   [docsort]


 IF ([numEntries].LT.[lowest30sd]) [lowest30sd] = [numEntries]

 ; ---------------------------------------------------------
 ; Local variance: ; get the images, measure average of each
 ; quadrant. Calculate mean,var of the 4 averages

 DO [key] = 1,[lowest30sd]

   UD [key],[stdev],[winTopLeftX],[winTopLeftY]   ; Get (key), std_dev, x coord, y coord
     [docsort]

   WI 
     [mic]
     [temp_mic_win]
     [sp_winsiz],[sp_winsiz]        ; Dimensions
     [winTopLeftX],[winTopLeftY]    ; Top left coords

   ; Get data from the four subimages
   [v93] = 1    ; not used?
   [v94] = 1    ; not used?
   [micWinSize] = int([sp_winsiz]/2)

   ; ------------------------------ 1

   WI
     [temp_mic_win]
     [temp_noise_win]
     [micWinSize],[micWinSize]
     1, 1

;   FS [v71],[v72],[v73],[v74]
;     [temp_noise_win]
;   
;   [v61] = [v73] ; the average value
   
   FI H [avg1]
     [temp_noise_win]

   ; ------------------------------ 2
   WI
     [temp_mic_win]
     [temp_noise_win]
     [micWinSize],[micWinSize]
     [micWinSize]-1, 1 

;   FS [v71],[v72],[v73],[v74]
;     [temp_noise_win]
;
;   [v62] = [v73] ; the average value

   FI H [avg2]
     [temp_noise_win]
     
   ; ------------------------------ 3
   WI
     [temp_mic_win]
     [temp_noise_win]
     [micWinSize],[micWinSize]
     1, [micWinSize]-1 

;   FS [v71],[v72],[v73],[v74]
;     [temp_noise_win]
;
;   [v63] = [v73]                      ; The average value

   FI H [avg3]
     [temp_noise_win]
     
   ; ------------------------------ 4
   WI
     [temp_mic_win]
     [temp_noise_win]
     [micWinSize],[micWinSize]
     [micWinSize]-1,[micWinSize]-1 

;   FS [v71],[v72],[v73],[v74]
;     [temp_noise_win]
;
;   [v64] = [v73]                     ; The average value

   FI H [avg4]
     [temp_noise_win]
     
   ; mean
   [avg] = ([avg1] + [avg2] + [avg3] + [avg4]) / 4
   
   ; sum (becomes variance of image averages)
   [var] = 0
   [var] = [var] + ([avg1] - [avg])**2
   [var] = [var] + ([avg2] - [avg])**2
   [var] = [var] + ([avg3] - [avg])**2
   [var] = [var] + ([avg4] - [avg])**2

   SD [key], [var],[stdev],[winTopLeftX],[winTopLeftY]   ; Put (key), var, std_dev, x coord, y coord
     [docvar]

 ENDDO

 ; --------------------------------------------------------
 DOC SORT     ; Sort docfile according to std_dev (column 1)
   [docvar]
   [docvarsort]
   1 
   Y

 ; Get windows sorted by lowest variance
 DO [key] = 1, [lowest30sd]

   UD [key],[v79], [stdev],[winTopLeftX],[winTopLeftY]   ; Get (key), var, std_dev, x coord, y coord
     [docvarsort]

   WI 
     [mic]
     [output]{***[key]}
     [sp_winsiz],[sp_winsiz]           ; Dimensions
     [winTopLeftX],[winTopLeftY]                       ; Top left coords
 ENDDO

 IF ([cleanYN].EQ.1) THEN
    DE
      [docnoise]
    DE
      [docsort]
    DE
      [docvar]
    UD E
      ;[docvarsort]  'UD E' takes no argument, but it's closing this file
    DE
      [docvarsort]
 ENDIF

 ; Select one at random
 [randomNum] = int(RAN(0) * ([lowest30sd] - 1)) + 1

 CP
   [output]{***[randomNum]}
   [noise]

 SYS
   echo ' 'Selected: [output]{***[randomNum]}.$DATEXT  for the noise file
 SYS
   echo ' '

 IF ([viewYN] .EQ. 1) THEN
   SYS
     qview [noise].$DATEXT &
 ELSEIF ([viewYN] .GE. 2) THEN
   SYS
     montage-spi -a [output]*.$DATEXT
 ENDIF
 
 EN

 ; Modified 2016-11-09
 ;    2016-11-09 (trs) -- micrograph list had been required
 ;    2016-11-09 (trs) -- bug fixes: extra parentheses, random img number was sometimes 0
 ;    2016-05-24 (trs) -- renamed previously unnamed register variables
 ;    2016-02-03 (trs) -- added option to display all noise images
 ;    2016-02-03 (trs) -- no longer converts micrograph, should exist in SPIDER format already
 ;    2015-10-12 (trs) -- optionally chooses micrograph to choose from

 ;