; dbck
;
; check all current assignment data-bases for integrity
;
; due to a bug in the foreach code, This command may have to
; be applied more than once in case of wrong entries.
;

;connect dbck.log

set case = (1 == 0)
if ($arg) then
   set case = $_
   if (toupper($case) s= "REMOVE") then
      set case = (1 == 1)
   else
      print 'Usage : dbck [ remove ]'
      error 'Wrong argument to dbck'
   endif
endif
      
;loop over the tests to insure redundancy
set done = (1==0)
while ( ! $done)
set done = (1==1)
;===============================================================
Print "checking ATT......."
set atmax = 0
set lrg = $att['LARGEST']
initinprogress $lrg   set j = 0
set i = 1
for i = 1 to $att["LARGEST"]
   if (exist('att[' // $i // ']')) then
; check index
     if ($i > $lrg) then
	print ("Error in ATT, peak #",$i, "present, whereas LARGEST is";$lrg)
	print "Removing this one"
	unset ('att[' // $i // ']')   ; this is probably a bit risky !
	set done = (1==0)
     else
   	set atmax = (max($atmax,$i))
     endif
; check coordinates
     set at = $att[$i]
     set f1 = (ptoh(head($at),2,1)) set at = (tail($at))
     set f2 = (ptoh(head($at),2,2)) set at = (tail($at))
     if ($f1 < $OFFSET_1_2D | $f1 > ($SPECW_1_2D +$OFFSET_1_2D) ) then
	print ("Peak #" ; $i; $att[$i]; "outside F1 spectral limit")
     endif
     if ($f2 < $OFFSET_2_2D | $f2 > ($SPECW_2_2D +$OFFSET_2_2D) ) then
	print ("Peak #"; $i; $att[$i]; "outside F2 spectral limit")
     endif
     set j = (%+1)   inprogress $j
; check amplitude
     set amp = (head($at))  set at = (tail($at))
     if ($amp s= ' ') then
        print ("Peak #" ; $i; $att[$i]; ": Wrong amplitude")
        print "Setting it to 1.0"
        set amp = 1.0
        set att[$i] = (htop($f1,2,1); htop($f2,2,2); $amp; $sp1; $sp2; $at)
	set done = (1==0)
     endif
     set sp1 = (head($at))  set at = (tail($at))
     set sp2 = (head($at))  set at = (tail($at))
; check spin existence and alignment
     if (toupper($sp1) s! 'UNK') then
        if (! exist('spin[' // $sp1 // ']')) then
          print ("Peak #" ; $i; $att[$i]; "assigned to Spin #"; $sp1; "not in SPIN db")
	  print "Setting it to 'UNK'"
	  set sp1 = 'UNK'
	  set att[$i] = (htop($f1,2,1); htop($f2,2,2); $amp; $sp1; $sp2; $at)
	  set done = (1==0)
	else
	  set spf1 = (head($spin[$sp1]))
	  set ddd = (abs(htop($f1,2,1)-$spf1))
	  if  ($ddd > $tol_align) then
		set ddd = (0.001 * int(1000*$ddd))
		print ('Warning: Peak #' ; $i; "assigned to Spin #"; $sp1; "- but are"; $ddd;"ppm apart")
	  endif
	endif
     endif
     if (toupper($sp2) s! 'UNK') then
	if  (! exist('spin[' // $sp2 // ']')) then
          print ("Peak #" ; $i; $att[$i]; "assigned to Spin #"; $sp2; "not in SPIN db")
	  print "Setting it to 'UNK'"
	  set sp2 = 'UNK'
	  set att[$i] = (htop($f1,2,1); htop($f2,2,2); $amp; $sp1; $sp2; $at)
	  set done = (1==0)
	else
	  set spf2 = (head($spin[$sp2]))
	  set ddd = (abs(htop($f2,2,2)-$spf2))
	  if  ($ddd > $tol_align) then
		set ddd = (0.001 * int(1000*$ddd))
		print ('Warning: Peak #' ; $i; "assigned to Spin #"; $sp2; "- but are"; $ddd;"ppm apart")
	  endif
	endif
     endif
; check spin alignment

   endif
endfor
if ($lrg != $atmax) then
	set att['LARGEST'] = $atmax
	print ("Resetting LARGEST to"; $atmax; "(was"; $lrg; ")" )
endif
inprogress $lrg

;===============================================================
Print "checking SPIN......."
set spmax = 0
set lrg = $spin['LARGEST']
initinprogress $lrg   set j = 0
for i = 1 to $spin["LARGEST"]
   if (exist('spin[' // $i // ']')) then
; check index
     if ($i > $lrg) then
	print ("Error in SPIN #";$i; "present, whereas LARGEST is"; $lrg)
	print "Removing this one"
	unset ('spin[' // $i // ']')
	set done = (1==0)
     else
   	set spmax = (max($spmax,$i))
     endif
; check sys
     set sp = $spin[$i]
     set f1 = (head($sp))   set sp = (tail($sp))
     set nm = (head($sp))   set sp = (tail($sp))
     set ss = (head($sp))   set sp = (tail($sp))
     if (toupper($ss) s= 'UNK') then
	print ("Warning : Spin #" ; $i; $spin[$i]; ": not in any Spin System")
	if ($case) unset ('spin[' // $i // ']')  print 'Removed' set done = (1==0)
     else
        if (! exist('sys[' // $ss // ']')) then
          print ("Spin #" ; $i; $spin[$i]; "defined to belong to a not existing System"; $ss)
          print "      Removing it from SPIN db"
      	  unset ('spin[' // $i // ']')
	  set done = (1==0)
        else                 ; check return assignment
          set sy = $sys[$ss]
          set sy = (tail(tail($sy)))    ; skip 2 first entries
          set ok = (1 == 0)
          while ($sy s! ' ')
             set s = (head($sy))  set sy = (tail($sy))
             set ok = ($ok | ($s == $i) )
          endwhile
          if (! $ok) then
             print ("WARNING : Spin #" ; $i; $spin[$i]; "defined to belong to Sys"; $ss)
             print ("   but Sys #"; $sys[$ss]; "does not know about it")
	     if ($case) then
                unset ('spin[' // $i // ']')  print 'Removed'
             else
                print "Assigning it to to UNK" 
                set spin[$i] = ($f1; $nm; 'UNK'; $sp)
             endif
	     set done = (1==0)
          endif
        endif
     endif
   endif

   set j = (%+1)   inprogress $j
endfor
if ($lrg != $spmax) then
	set spin['LARGEST'] = $spmax
	print ("Resetting LARGEST to"; $spmax; "(was"; $lrg; ")" )
endif
inprogress $lrg

;===============================================================
Print "checking SYS......."
set ssmax = 0
set lrg = $sys['LARGEST']
initinprogress $lrg   set j = 0
for i = 1 to $sys["LARGEST"]
   if (exist('sys[' // $i // ']')) then
     if ($i > $lrg) then
	print ("Error in SYS #";$i; "present, whereas LARGEST is"; $lrg)
	print "Removing this one"
	unset ('sys[' // $i // ']')
	set done = (1==0)
     else
   	set ssmax = (max($ssmax,$i))
     endif
;detect system without spin
     set ss = $sys[$i]
     set num = (head($ss))
     set aa = (head(tail($ss)))
     set splist = (tail(tail($ss)))
     if ($splist s= " ") then
	print ("Error in SYS #";$i; ": System without spin")	
        print "Removing this one"
        unset ('sys[' // $i // ']')
        set done = (1==0)
;detect system with unknows spins
     else
	while ($splist s! " ")
          set sp = (head($splist))  
          set splist = (tail($splist))
	  if ( ! exist('spin[' // $sp // ']')) then
		print ("Error in SYS #";$i; " unknow spin"; $sp)
		print "Removing this one"
		@rem_spin_sys $i $sp	
		set done = (1==0)
	  endif
	endwhile
     endif
   endif
   set j = (%+1)   inprogress $j
endfor
if ($lrg != $ssmax) then
	set sys['LARGEST'] = $ssmax
	print ("Resetting LARGEST to"; $ssmax; "(was"; $lrg; ")" )
endif

inprogress $lrg

;end of loop
endwhile

;===============================================================
Print "checking Duplicate Spins......."

initinprogress $sys["LARGEST"]
for i = 1 to $sys["LARGEST"]
   inprogress $i
   if (exist('sys[' // $i // ']')) then
     set ss = $sys[$i]
     set num = (head($ss))
     set aa = (head(tail($ss)))
     set splist = (tail(tail($ss)))
        while ($splist s! " ")
          set sp = (head($splist))
          set splist = (tail($splist))
          for k = ($i+1) to $sys["LARGEST"]
            if (exist('sys[' // $k // ']')) then
                set ss2 = $sys[$k]
                set num2 = (head($ss2))
                set aa2 = (head(tail($ss2)))
                set splist2 = (tail(tail($ss2)))
                while ($splist2 s! " ")
                  set sp_2 = (head($splist2))
                  set splist2 = (tail($splist2))
                  if ( $sp s= $sp_2 ) then
                    print (" Warning, Spin #";$sp; "is found in two systems: #";$i;"and #";$k)
                  endif
                endwhile 
            endif
          endfor
	endwhile
    endif
endfor

; disconnect

