#!/usr/sbin/perl
#
# Azat Badretdinov:
# 23 May 1998:
#
# top2rad takes as input CHARMM topology library
# it also reads $RADII_LIB and RADII14_LIB from environment
# restyp from top.ini
# Output: new RADII_LIB  and RADII14_LIB and restyp be written to 
# ARGV[0] and [1] and [2] or, alternatively
# if "update" is the first argument, the editing is done in place
#
# Example: cat top*.inp | top2rad /tmp/1 /tmp/2  /tmp/3
#       or cat top*.inp | top2rad update
#       or cat top*.inp | top2rad update rest does not matter 
if(@ARGV != 3 && $ARGV[0] ne "update" )
  {
  print `cat "$0.default"`;
  exit;
  }
$update = $ARGV[0] eq "update";
# readings and settings
  $nmodels = 9;
  for($i=0;$i<17;$i++, $seventeen.=" "){}
  for($i=0;$i<$nmodels;$i++)
      {
      $radii_default.= sprintf("%6.2lf",0.0);
      }
  $radii_lib = $ENV{'RADII_LIB'};
  $radii14_lib = $ENV{'RADII14_LIB'};
  $LIB = $ENV{'MODINSTALL'}."/modlib";
  ($restyp_lib)= grep ( /^\s*\d+\s+STRING\s+RESTYP_LIB_FILE/ && s/\n//,
                 `cat "$LIB/top.ini"`);
# print "restyp_lib 1: $restyp_lib\n";
  ($restyp_lib)= $restyp_lib=~/\'([^\']+)\'/;
# print "restyp_lib 2: $restyp_lib\n";
  $restyp_lib=~s/\$\(LIB\)/$LIB/;
# print "restyp_lib 3: $restyp_lib\n";
  ($nradii_lib,$nradii14_lib,$nrestyp_lib) =  ($radii_lib,$radii14_lib,$restyp_lib);
  $nradii_lib   = $ARGV[$i++] if($i < @ARGV && !$update);
  $nradii14_lib = $ARGV[$i++] if($i < @ARGV && !$update);
  $nrestyp_lib  = $ARGV[$i++] if($i < @ARGV && !$update);
  @input = <STDIN>;
  @mass = grep( /^MASS\b/ && s/\n//,@input);
  @resi = grep( /^(RESI|PRES) /  && s/\n//,@input);
  @restyp   = grep ( /^[^#]/ && /^\s*\d+\s+\|/  && s/\n//, `cat $restyp_lib`);
  @radii   = grep ( /^[^#]/ && /^\s*\d+\s+[A-Z]/ && s/\n//, `cat $radii_lib`);
  @radii14 = grep ( /^[^#]/ && /^\s*\d+\s+[A-Z]/ && s/\n//, `cat $radii14_lib`);

# read old last numbers
# read old atom and res names, radii and assign them to full and 1letter atom names
  $nradii=$nradii14=$nrestyp=0;
  foreach $line (@restyp)
    {
    ($n,$pdb_names,$pdb_name1, $charmm, $comment) =split(/\|/,$line, 5);
    $charmm=~s/\s//g; $n=~s/\s//g;
    @pdb_names= sort grep(/\S/, split(' ', $pdb_names));
    push(@rname,$charmm);
    $pdb_names{$charmm}=join(' ', @pdb_names);
    $nrestyp = $n if ($n > $nrestyp);
    }
  foreach $line (@radii)
    {
    ($n,$name,@F) =split(' ',$line);
    $name1=substr($name,0,1);
    local($new1)= !defined($radii_1{$name1});
    $radii_1{$name1}="" if $new1;
    $radii{$name}=""; for($i=0;$i<$nmodels;$i++)
      {
      $t = sprintf("%6.2lf",$F[$i]);
      $radii{$name}.=$t;
      $radii_1{$name1}.=$t if $new1;
      }
    $radii{$name}=~s/\n//;
    $radii_1{$name1}=~s/\n//; 
    push(@aname,$name);
    $nradii = $n if ($n > $nradii);
    }
  foreach $line (@radii14)
    {
    ($n,$name,@F) =split(' ',$line); 
    $name1=substr($name,0,1);
    local($new1)= !defined($radii14_1{$name1});
    $radii14_1{$name1}="" if $new1;
    $radii14{$name}=""; for($i=0;$i<$nmodels;$i++)
      {
      $t = sprintf("%6.2lf",$F[$i]);
      $radii14{$name}.=$t;
      $radii14_1{$name1}.=$t if $new1;
      }
    $radii14{$name}=~s/\n//;
    $radii14_1{$name1}=~s/\n//; 
    push(@aname14,$name);
    $nradii14= $n if ($n > $nradii14);
    }
# read new names
  foreach $line (@resi)
    {
    ($n,$name,$value, $symbol, $comment) =split(' ',$line, 5);  # RESI or PRES
    $name=~tr/a-z/A-Z/;
    if (!grep ($name eq $_, @new_rname,   @rname))
      {
      $pdb_names{$name}=substr($name, 0, 3);
# check and warn if new pdb name coinside with previous one
      foreach $oldname (@new_rname,   @rname)
        {
	if (grep($pdb_names{$name} eq $_, split(' ', $pdb_names{$oldname})))
	  {
	  print "$0: warning: PDB name ($pdb_names{$name}) of new CHARMM name ($name) ", 
	    "coinsides with one of previously defined PDB names ($pdb_names{$oldname}) ", 
	    "of CHARMM name ($oldname)\n";
	  }
	}
      push(@new_rname,$name);
      }
    $rcomment{$name}=$comment;
    }
  foreach $line (@mass)
    {
    ($t,$n,$name,$weight, $comment) =split(' ',$line,5);
    $name=~tr/a-z/A-Z/;
    push(@new_aname,  $name) if !grep ($name eq $_, @new_aname,   @aname);
    push(@new_aname14,$name) if !grep ($name eq $_, @new_aname14, @aname14);
    $acomment{$name}=$comment;
    }
# for each new new name assign a radius
  foreach $name (@new_aname)
    {
    $name1=substr($name,0,1);
    $radii{$name}= defined ($radii_1{$name1}) ? $radii_1{$name1} : $radii_default;
    }
  foreach $name (@new_aname14)
    {
    $name1=substr($name,0,1);
    $radii14{$name}= defined ($radii14_1{$name1}) ? $radii14_1{$name1} : $radii_default;
    }
# copy the file(s) and append them
  `/bin/cp $radii_lib $nradii_lib` if ($radii_lib ne $nradii_lib);
  `/bin/cp $radii14_lib $nradii14_lib` if ($radii14_lib ne  $nradii14_lib);
  `/bin/cp $restyp_lib $nrestyp_lib` if ($restyp_lib ne  $nrestyp_lib);
  foreach $name (sort @new_aname)
    {
    $line = sprintf("%3d %-4.4s%s  %s", ++$nradii, $name,$radii{$name},$acomment{$name});
    `echo "$line" >> $nradii_lib`;
    }
  foreach $name (sort @new_aname14)
    {
    $line = sprintf("%3d %-4.4s%s  %s", ++$nradii14, $name,$radii14{$name},$acomment{$name});
    `echo "$line" >> $nradii14_lib`;
    }
  foreach $name (sort @new_rname)
    {
    $line = sprintf("%3d | %-3.3s$seventeen| # | %-4.4s | %s", 
      ++$nrestyp, $pdb_names{$name}, $name, $rcomment{$name});
    `echo "$line" >> $nrestyp_lib`;
    }
    
  print `cat $0.warnings`;
