; Controls and synchronizes refinement
;
; FILE: pub_refine.pam                           ArDean Leith Nov 2000
;                                                ArDean Leith Mar 2004
;                          [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
;                          Newdala removed       ArDean Leith Mar 2006
;                          Ampenhance fixed      ArDean Leith May 2006
;                          More stacks           ArDean Leith Dec 2006
;                          MP = 1                ArDean Leith Jan 2008
;
; MASTER COPY: /net/bali/usr1/spider/docs/techs/recon/newprogs/
;
; PURPOSE: Runs on one node to control and synchronize refinement
;
; I/O Registers & files are set in: refine settings refine settings.pam.pam)
;
; INPUT REGISTERS:
;    [maxspfreq]              Maximum spatial freq[a-1] (used in prepare)
;    [radius]                 Radius of structure
;    [alignsh]                Shift allowed is +-[alignsh]
;    [iter-end]               Ending   iteration
;    [lambda]                 Lambda(angstroms) (used in prepare)
;
;  '##' denotes iteration,  '##+' denotes next iteration, and '***' denotes group
; INPUT FILES:
;    [order_select]           input/order_select        Group selection file
;    [sorted_order_select]    input/order_select_sort   Sorted group selection file
;    [unaligned_images]       input/data***             Unaligned stacked image files
;    [aligned_images]         input/dala01_***          Aligned stacked image files
;    [start_group_align]      input/align_01_***        Alignment parameter input file 
;    [start_vol]              input/vol01               Initial starting volume
;
; PROCEDURES CALLED:
;    refine_settings          refine_settings.pam
;    sort                     sort.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  
;    ... saveresp             saveresp.pam
;
; ---------------------------------------------------------------------

MD
TR OFF                       ; Loop info turned off
MD
VB OFF                       ; File info turned off
MD
() OFF                       ; No need for () in DO loops          
MD
SET MP                       ; Use single OMP processor
1

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

IF([iter1].LE.1)THEN
   ; Prepare input files (only needs to be done once)  
   @prepare([maxspfreq],[lambda],[iter1])
ENDIF

[xdum]=0.0

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

   FT                         ; Fourier on volume 
   [current_vol]              ; Volume produced by previous iter.   
   [iter_vft]                 ; Used by all groups on this iter. in xoop - vft

   ; Create ref. angle & ref. selection doc files for this iteration 
   DE
   [iter_ang_voea]            ; Ref. angles doc file
   DE
   [iter_select_voea]         ; Ref. angle selection doc file 

   RR S [ang-step]            ; Angular step (varies with iteration)
   ([ang-steps])
   [iter]
   RR S [ang-limit]           ;  Restriction on ang. search degrees (varies with iteration)
   ([ang-limits])
   [iter]
   RR S [ampenhance]          ;  Amplitude enhancement register setting (varies with iteration)
   ([amp-enhance-flags])
   [iter]

   IF ([small-ang].EQ.0) THEN
      ; For regular angle refinement
      VO EA,[num-angles]      ; Sets [num-angles] to number of reference projections
      [ang-step]              ; Angular step (varies with iteration)
      (0,90.0)                ; Angles
      (0,359.9)               ; Angles
      [iter_ang_voea]         ; Create ref. angles doc file    (output)
   ELSE
      ; For SMALL angle refinement
      VO EA,[num-angles]      ; Sets [num-angles] to number of reference projections
      [ang-step]              ; Angular step 
      (0,[ang-limit])         ; SMALL Angles
      (0,0)                   ; SMALL Angles
      [iter_ang_voea]         ; Create ref. angles doc file    (output)
   ENDIF

   DOC CREATE                 ; Create ref. angle selection doc file   
   [iter_select_voea]         ; Ref. angle selection doc file  (output)
   (1)                        ; First register
   1-[num-angles]             ; Select all angles
  
   ; Find number of defocus groups
   UD N [num-grps]                
   [sorted_order_select]

   ; Generate random number ([rn]) for unique DOC_SYNC files
   [rn]=int(ran([xdum])*9999)

   ; Process all defocus groups in parallel
   [task] = [small-ang]       ; Pub_starter selector flag
   DO LB3 [i]=1,[num-grps]
      UD IC [i],[grp]         ; Get this defocus group number
      [sorted_order_select]

      ; Use pub_refine_start to create parallel grploop for each defocus group   
      VM
      publish './spider pam/$DATEXT @pub_refine_start {***[grp]} task={*[task]} iter={**[iter]} grp={***[grp]} rn={****[rn]}' 
      ;
   LB3

   UD ICE                     ; End doc file UD ICE use
   [sorted_order_select]

   VM
   date '+ TIME: %x  %X'

   VM
   echo " Waiting for iteration: {**[iter]}"
   MY FL   ; Flush results file

   ;  Wait for all subscribers to finish grploop, returns [num-big]
   [task] = 0               ; Pub_starter selector flag
   @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 now
   IF([num-big].EQ.0) GOTO LB71  

   ; Consolidate data for CTF corrections
   @mergegroups([maxspfreq],[iter],[ampenhance])

   DE                       ; Delete vft file.
   [iter_vft]               ; Used by all groups this iter.  

   DE                       ; Delete ref. angle selection file
   [iter_select_voea]       ; Ref. angle selection doc file 

   MY FL   ; flush results
LB1

LB71

VM
date '+ TIME: %x  %X'
VM
echo " Alignment halting after iteration: {***[iter]}"
VM
echo " "

; Start up endmerge using PubSub

DO LB11 [i]=1,[num-grps]     
   UD S [i],[grp]       ; Get defocus group number 
   [sorted_order_select]

   ;By setting [task]=2 pub_refine_start starts: endmerge 
   VM
   publish './spider pam/$DATEXT @pub_refine_start {***[grp]} task=2 iter={**[iter]} grp={***[grp]} rn={****[rn]}' 
LB11

UD E                    ; End doc file UD use

VM
date '+ TIME: %x  %X'
VM
echo " Waiting for endmerge for iteration: {**[iter]}"
MY FL                   ; Flush results

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

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

VM
date '+ TIME: %x  %X'
VM
echo " SUCCESS, REFINEMENT FINISHED"

EN
;