; Controls and synchronizes refinement
;
; SOURCE: spider/docs/techs/recon/newprogs/pub_refine.pam
;
;         New                              ArDean Leith  Nov 2000
;         [rn] for endmerge                ArDean Leith  May 2005
;         [] from publish                  ArDean Leith  Feb 2006
;         Ampenhance                       ArDean Leith  May 2006
;         More stacks                      ArDean Leith  Dec 2006
;         Existing iter_refangs bug        ArDean Leith  Aug 2010
;         COG centering                    ArDean Leith  Sep 2010
;         Dala files removed               ArDean Leith  Jan 2012
;         pixsiz, resol headers,...        ArDean Leith  Aug 2012
;         [n-big]                          ArDean Leith  Apr 2015
;
; PURPOSE: Runs on master node to control PubSub refinement
;
; I/O Registers & files are set in: refine settings.pam
;
; INPUT REGISTERS:
;   [maxspfreq]              Maximum spatial freq (1/A) (used in prepare)
;   [r2]                     Radius of object 
;   [alignsh]                Translation shift allowed is +-[alignsh]
;   [iter-end]               Ending iteration
;   [lambda]                 Lambda (A) (used in prepare)
;
; '##' denotes iteration,  '##+' denotes next iteration, and '***' denotes group
; INPUT FILES:
;   [params]                ../params                             Params file  
;   [vol_orig]              ../Reconstruction/vol01               Starting volume file  
;   [sel_group_orig]        ../Reconstruction/sel_group_cclim     Group selection file
;   [sel_particles_orig]    ../Reconstruction/sel_particles_***   Particle selection files 
;   [group_align_orig]      ../Alignment/align_01_***             Initial alignment parameter files 
;   [unaligned_images]      ../Alignment/data***                  Original unaligned images stacks
;
; PROCEDURES CALLED:
;    refine_settings          refine_settings.pam
;    prepare                  prepare.pam
;
;    publish                  publish
;    ... pub_refine_start      pub_refine_start          
;    ....... refine_settings  refine_settings.pam            
;    ....... grploop          grploop.pam            
;    ....... smangloop        smangloop.pam            
;    ....pub_refine_doc_sync  pub_refine_doc_sync.pam
;    pub_refine_wait          pub_refine_wait.pam
;
;    mergegroups              mergegroups.pam
;    ... enhance              enhance.pam
;    publish                  publish
;    ...  pub_refine_start    pub_refine_start        
;    ...... refine_settings   refine_settings.pam            
;    ...... endmerge          endmerge.pam
;    ....pub_refine_doc_sync  pub_refine_doc_sync.pam
;    pub_refine_wait          pub_refine_wait.pam
; 
;    endrefine                endrefine.pam  
;
; ---------------------------------------------------------------------

 MD
   TR OFF                    ; Loop info turned off
 MD
   VB OFF                    ; File info turned off
 MD
   SET MP                    ; Use single processor on master node!!
   1

 ; Input initial parameters & file names but not angular steps
 @refine_settings([pixsiz],[r2],[alignsh],[prj-radius],[iter1],[iter-end],[lambda],[small-ang],[winsize])

 IF ( [iter1] <= 1 ) THEN 
    ; Prepare input files (only needs to be done once)  
    @prepare([pixsiz],[lambda],[iter1])  
 
    SD /     ITERATION        GROUP       RESOLUTION
      [iter_resol]          ; Resolution doc file               (output)
    SD /     ITERATION        GROUP       RESOLUTION
      [grp_resol]           ; Resolution doc file               (output)
    SD E     
      [grp_resol]           ; Resolution doc file               (finished)
 ENDIF

 UD N [num-grps]             ; Find number of defocus groups
   [sel_group_sorted]        ; Defocus group selection file      (input)

 DO [iter]=[iter1],[iter-end]; Loop over all iterations ----------------------------------

   FT                        ; Fourier on volume 
     [current_vol]           ; Volume produced by previous iter. (input)  
     [iter_vft]              ; For all groups on this iter.      (output)

   RR S [ampenhance]         ; Amplitude enhancement reg. setting (varies with iteration)
     [amp-enhance-flags]
     [iter]
 
   DE
     [iter_refangs]          ; Reference angles doc file          (removed)

   ; Create reference angle doc file for this iteration 

    IF( [small-ang] == 0 ) THEN  
      ; Usual case.  For normal angle refinement
      RR S [ang-step]
        [ang-steps]           ; Angular step for projection angle  (varies with iteration)
        [iter]

      VO EA [num-angles]      ; Sets [num-angles] to number of reference projections
        [ang-step]            ; Theta angular step          (varies with iteration)
        0, 90.0               ; Theta range, 90 is for use with 'Check Mirrored Positions'
        0, 359.9              ; Phi range
        [iter_refangs]        ; Reference angles doc file       (output)

      RR S [ang-limit]        ; Restriction on angular search   (varies with iteration)
        [ang-limits] 
        [iter]

   ELSE                       
      ; For Small angle refinement
      VO EA [num-angles]      ; Sets [num-angles] to number of reference projections
        [ang-step-sm]         ; Theta angular step     
        0,[theta-range]       ; Theta range 
        0, 359.9              ; Phi range
        [iter_refangs]        ; Reference angles doc file        (output)
 
    ENDIF

   ; Generate 4 digit random number for semi-unique DOC_SYNC file numbering
   [rn] = int(ran(0.0)*9999)

   ; Process all defocus groups in parallel
   [task] = [small-ang]       ; Pub_starter selector flag

   DO [i]=1,[num-grps]        ; Loop over all groups ---------------------------
      UD IC [i],[grp]         ; Get this defocus group number
        [sel_group_sorted]    ; Defocus group selection file     (input)

      ; Use pub_refine_start to create parallel grploop for each defocus group   
      SYS
        publish './spider $PRJEXT/$DATEXT @pub_refine_start {%I0%[grp]} task={%I0%[task]} iter={%I0%[iter]} grp={%I0%[grp]} rn={****[rn]}' 
      
   ENDDO

   UD ICE                     ; End doc file 'UD IC' use
     [sel_group_sorted]

   ;  Wait for all subscribers to finish grploop, returns [num-big]
   [task] = 0                 ; When [task]=0, pub_refine_start starts: grploop
   @pub_refine_wait([task],[num-big],[num-grps],[iter],[rn])

   ; [num-big] returns number of groups having excessive changes
   ; (this is summed in: pub_refine_wait)
   SYS
     echo " After pub_refine_wait, Excessive changes in: {%I0%[num-big]} groups"

   ; Consolidate data for CTF corrections, create iteration's output volume
   @mergegroups([pixsiz],[iter],[ampenhance],[r2])

   DE                         ; Delete existing iterations Fourier vol.
     [iter_vft]               ; Fourier file                     (removed)                

   SYS
     echo " Iteration: {**[iter]} Finished"

   MY FL                      ; Flush results
 ENDDO

 SYS                           ; Echo current time 
   echo -n " Alignment halting after iteration: {%I0%[iter]}   " ; date '+ TIME: %x  %X' ; echo " " 

 ; Start up endmerge using PubSub
 DO [i]=1,[num-grps]          ; Loop over all groups ----------------------
    UD IC [i],[grp]           ; Get this defocus group number
      [sel_group_sorted]      ; Defocus group selection file  (input)

    SYS                        ; When [task]=2, pub_refine_start starts: endmerge 
      publish './spider $PRJEXT/$DATEXT @pub_refine_start {%I0%[grp]} task=2 iter={%I0%[iter]} grp={%I0%[grp]} rn={****[rn]}' 
 ENDDO

 UD ICE                       ; End doc file incore use for [sel_group_sorted]
   [sel_group_sorted]

 ; Wait for all parallel endmerge tasks
 [task]=2
 @pub_refine_wait([task],[num-big],[num-grps],[iter],[rn])

 ; Prepare final resolution files
 @endrefine([r2],[pixsiz],[iter])    

 SYS                          ; Echo current time 
   echo -n " REFINEMENT FINISHED   " ; date '+ TIME: %x  %X'

 EN
;