; Controls and synchronizes refinement
;
; SOURCE: spider/docs/techs/recon/newprogs/pub_refine.pam
;
;         New                                           ArDean Leith  Nov 2000
;         [rn]                                          ArDean Leith  Feb 2005
;         [rn] for endmerge                             ArDean Leith  May 2005
;         []                                            ArDean Leith  Dec 2005
;         "" on publish line                            ArDean Leith  Jan 2006
;         [] from publish                               ArDean Leith  Feb 2006
;         Ampenhance                                    ArDean Leith  May 2006
;         More stacks                                   ArDean Leith  Dec 2006
;         MP = 1                                        ArDean Leith  Jan 2008
;         File locations changed                        ArDean Leith  Oct 2009
;         Existing iter_refangs bug                     ArDean Leith  Aug 2010
;         COG centering                                 ArDean Leith  Sep 2010
;         Dala files removed                            ArDean Leith  Jan 2012
;
; PURPOSE: Runs on master node to control PubSub refinement
;
; I/O Registers & files are set in: refine settings.pam
;
; INPUT REGISTERS:
;   [sp_maxspfreq]           Maximum spatial freq (1/A) (used in prepare)
;   [radius]                 Radius of structure 
;   [alignsh]                Shift allowed is +-[alignsh]
;   [iter-end]               Ending iteration
;   [sp_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
;    ... saveresp             saveresp.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  
;    ....softmask             softmask.pam            
;    ... saveresp             saveresp.pam
;
; ---------------------------------------------------------------------

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

; Input initial parameters & file names but not angular steps
@refine_settings([sp_maxspfreq],[radius],[alignsh],[prj-radius],[iter1],[iter-end],[sp_lambda],[small-ang],[sp_winsize],[converg])

IF([iter1].LE.1)THEN
   ; Prepare input files (only needs to be done once)  
   @prepare([sp_maxspfreq],[sp_lambda],[iter1])
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.   
   [iter_vft]                 ; Used by all groups on this iter. in xoop - vft

   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].EQ.0) THEN  

      ; 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 Positons:1'
      (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                    ; Small angle refinement

      ; 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]

      ; Use pub_refine_start to create parallel grploop for each defocus group   
      VM
      publish './spider $PRJEXT/$DATEXT @pub_refine_start {***[grp]} task={*[task]} iter={**[iter]} grp={***[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],[converg],[rn])

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

   ; If angular changes were small in all groups, can stop iterations now
   IF([num-big].EQ.0) EXIT  

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

   DE                       ; Delete existing iterations Fourier vol.
   [iter_vft]                 

   VM
   echo " Iteration: {**[iter]} Finished"
   MY FL   ; Flush results
ENDDO

VM                          ; Echo current time 
echo -n " Alignment halting after iteration: {**[iter]}   " ; date '+ TIME: %x  %X'
VM
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)

   VM                       ; When [task]=2, pub_refine_start starts: endmerge 
   publish './spider $PRJEXT/$DATEXT @pub_refine_start {***[grp]} task=2 iter={**[iter]} grp={***[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],[converg],[rn])

; Prepare final resolution files
@endrefine([radius],[sp_maxspfreq],[iter])    

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

EN
;