#!/usr/bin/perl -w 
# matrixpdb.pl: It transform a pdb file using a
# matrix provided by Dali-server:
# Example:
# MATRICES: UX+T is the least-squares superimposition of STRID2 (X) onto STRID1
#  NR. STRID1 STRID2           U(.,1)    U(.,2)    U(.,3)         T(.)
#   2: 1fsz   1d0n-A  U(1,.)   0.263168 -0.892530 -0.366242       73.481804   
#   2: 1fsz   1d0n-A  U(2,.)   0.456831  0.449653 -0.767540        2.239058   
#   2: 1fsz   1d0n-A  U(3,.)   0.849734  0.034681  0.526069      -41.389801   


# Asking for orig and dest. files

print "\n Name of \"pdb\" file to be rotated? ";
$pdb_orig_file = <STDIN>;
chomp $pdb_orig_file; # Name of origen PDB file

if ($pdb_orig_file eq "") {
	die "\n";
}

$xx = 0;
while ($xx == 0) { # This loop is used to avoid overwriting dest. file if not desired

	$dest_file = "$pdb_orig_file.matrix";
	print "\n\nName of \"pdb\" destination file (* $dest_file *) ? ";
	$pdn_trans_file = <STDIN>;
	chomp $pdn_trans_file;  # Name of translated PDB file
	if ($pdn_trans_file eq "") {
		$pdn_trans_file = $dest_file;
	}
	if (-e "$pdn_trans_file") {
		print "\n \"$pdn_trans_file\" file already exists, overwrite it (y/n) ? [n] ";
		$yesno = <STDIN>;
		$yesno =~ tr/a-z/A-Z/;
		$yn = substr ($yesno, 0, 1);
		if ($yn eq "Y") {
			$xx = 1;
		}	
	} else {
		$xx=1;
	}
}


############ OPENING AND TESTING FILES & FILEHANDLES 


open (ORIGFILE, "$pdb_orig_file") || die "\n Sorry, I couldn't open \"$pdb_orig_file\".\n\n";

while (<ORIGFILE>) {
	push (@original, $_); #It creates @original from the pdb file lines
}
close ORIGFILE;
$numero_de_lineas = @original; 

open (TRANSLAFILE, ">$pdn_trans_file") || die " Sorry, I couldnīt create \"$pdn_trans_file\".\n\n";



######### DEFINITION OF MATRIX PARAMETERS. ASKING FOR THEM.

print STDERR "\n\nExample of superimposition matrix (FSSP - Dali):\n";

print STDERR"   2: 0401   2chs-A  U(1,.)  -0.478018 -0.570350  0.667982           34.183628\n";   
print STDERR"   2: 0401   2chs-A  U(2,.)   0.846948 -0.500832  0.178458          -26.953529\n"; 
print STDERR"   2: 0401   2chs-A  U(3,.)   0.232764  0.651052  0.722463          -64.771584\n\n"; 

$zz = 0;
while ($zz == 0) {
  print STDERR "\nPaste the matrix to be used \(3 lines at the same time\)\:\n\n";
  $matrixline1 = <STDIN>;
  $matrixline2 = <STDIN>;
  $matrixline3 = <STDIN>;
  &getmatrix;

  @pasa_array = 0;
  @UU =0;
  for ($ii=1; $ii<4; $ii++) {
    for ($jj=1; $jj<5; $jj++) {
      $UU[$ii][$jj] = $U[$ii][$jj];
      @UUU = split (//,$UU[$ii][$jj]);
      @pasa_array2 = @UUU;
      &ARREGLAVALOR2;
      @UUU = @pasa_array2;
      $UU[$ii][$jj] = join '',@UUU;
    }
  }


  print STDERR "\n The matrix in memory is\:\n\n";

  print STDERR "              U(.,1)        U(.,2)        U(.,3)        T(.)\n\n";
  print STDERR " U(1,.)   $UU[1][1]   $UU[1][2]   $UU[1][3]   $UU[1][4]\n";
  print STDERR " U(2,.)   $UU[2][1]   $UU[2][2]   $UU[2][3]   $UU[2][4]\n";
  print STDERR " U(3,.)   $UU[3][1]   $UU[3][2]   $UU[3][3]   $UU[3][4]\n";

  print STDERR "\n\n Use this matrix (y/n) ?  ";
  $correct = "XXXXXXXX";
  $xx = 0;
  while ($xx == 0) {
    $tt = 0;
    for ($tt = 0; $tt < 100; $tt++) {
      $correct = <STDIN>; 
      @correc = 0;
      @correc = split (' ',$correct);
      push @correc, "\n";
      $correct = join '', @correc;
      $correct =~ tr/a-z/A-Z/;
      $co = "Y";
      $co = substr ($correct, 0, 1);
      if ($co eq "Y") {
        $zz = 1;
        $xx = 1;
        $tt = 100;
      }
      elsif ($co eq "N") {
        $zz = 0;
        $xx = 1;
        $tt = 100;
      }
      else {
        print STDERR "\n Use this matrix (y/n) ?  ";
      }
    }
  }
}

########## COPY @original TO @translated AND CALL SUB TRANSLATION

@translated = 0;
$aa = 0;
for ($aa=0; $aa<$numero_de_lineas; $aa++) {
  @separa = 0;
  @separa = split (//,$original[$aa]); #split $original[$aa] using '' as delimiter => nothing as delimiter
  $long_linea = 0;
  $long_linea = @separa;
  $comprueba = "XXXXXX";
  $comprueba = pack "AAAAAA", $separa[0], $separa[1], $separa[2], $separa[3], $separa[4], $separa[5];
  if (($comprueba eq "ATOM  ") or ($comprueba eq "HETATM")) {
    &TRANSLATION;
  }
  else {
   $translated[$aa] = $original[$aa];
  }
   print TRANSLAFILE "$translated[$aa]";
   print STDERR ".";
}

close TRANSLAFILE;

print STDERR "\n\n\n ** \"$pdn_trans_file\" created successfully from \"$pdb_orig_file\" **  \n\n";

######## END OF MAIN PROGRAM


##### SUB GETMATRIX

sub getmatrix {

# U11 =  $U[1][1];  U12 = $U[1][2];  U13 = $U[1][3];  T1  = $U[1][4];
# U21 =  $U[2][1];  U22 = $U[2][2];  U23 = $U[2][3];  T2  = $U[2][4];
# U31 =  $U[3][1];  U32 = $U[3][2];  U33 = $U[3][3];  T3  = $U[3][4];

$ii = 1;
$jj =1;
@U = 0;
for ($ii=1; $ii<4; $ii++) {
  for ($jj=1; $jj<5; $jj++) {
    $U[$ii][$jj] = 0;
  }
}

chomp $matrixline1;
@matrixlinea1 = split (' ',$matrixline1); #split $matrixline1 using space as delimiter
$largoline1 = @matrixlinea1;
$U[1][4] = $matrixlinea1[($largoline1 -1)];
$U[1][3] = $matrixlinea1[($largoline1 -2)];
$U[1][2] = $matrixlinea1[($largoline1 -3)];
$U[1][1] = $matrixlinea1[($largoline1 -4)];

chomp $matrixline2;
@matrixlinea2 = split (' ',$matrixline2); #split $matrixline2 using space as delimiter
$largoline2 = @matrixlinea2;
$U[2][4] = $matrixlinea2[($largoline2 -1)];
$U[2][3] = $matrixlinea2[($largoline2 -2)];
$U[2][2] = $matrixlinea2[($largoline2 -3)];
$U[2][1] = $matrixlinea2[($largoline2 -4)];

chomp $matrixline3;
@matrixlinea3 = split (' ',$matrixline3); #split $matrixline3 using space as delimiter
$largoline3 = @matrixlinea3;
$U[3][4] = $matrixlinea3[($largoline3 -1)];
$U[3][3] = $matrixlinea3[($largoline3 -2)];
$U[3][2] = $matrixlinea3[($largoline3 -3)];
$U[3][1] = $matrixlinea3[($largoline3 -4)];

}
####### END OF SUB GETMATRIX


######### BEGIN SUB TRANSLATION

sub TRANSLATION {
  @XXBB = 0; @YYBB = 0; @ZZBB = 0; 
  $XA = 0; $YA = 0; $ZA = 0;
  $XB = 0; $YB = 0; $ZB = 0;

  $XA = join '', $separa[30], $separa[31], $separa[32], $separa[33], $separa[34], $separa[35], $separa[36], $separa[37];
  $YA = join '', $separa[38], $separa[39], $separa[40], $separa[41], $separa[42], $separa[43], $separa[44], $separa[45];
  $ZA = join '', $separa[46], $separa[47], $separa[48], $separa[49], $separa[50], $separa[51], $separa[52], $separa[53];

  $XB = ($XA * $U[1][1]) + ($YA * $U[1][2]) + ($ZA * $U[1][3]) + $U[1][4];
  $YB = ($XA * $U[2][1]) + ($YA * $U[2][2]) + ($ZA * $U[2][3]) + $U[2][4];
  $ZB = ($XA * $U[3][1]) + ($YA * $U[3][2]) + ($ZA * $U[3][3]) + $U[3][4];
  
  
  @pasa_array = 0;
  $XB = $XB + 0.0000000000001;
  @XXBB = split (//,$XB);
  @pasa_array = @XXBB;
  &ARREGLAVALOR;
  @XXBB = @pasa_array;

  @pasa_array = 0;
  $YB = $YB + 0.0000000000001;
  @YYBB = split (//,$YB);
  @pasa_array = @YYBB;
  &ARREGLAVALOR;
  @YYBB = @pasa_array;

  @pasa_array = 0;
  $ZB = $ZB + 0.0000000000001;
  @ZZBB = split (//,$ZB);
  @pasa_array = @ZZBB;
  &ARREGLAVALOR;
  @ZZBB = @pasa_array;


  $cc = 0;
  for ($cc = 0; $cc < 8; $cc++) {
    $separa[(30 + $cc)] = $XXBB[$cc]; 
  }  

  $cc = 0;
  for ($cc = 0; $cc < 8; $cc++) {
    $separa[(38 + $cc)] = $YYBB[$cc]; 
  }
 
  $cc = 0;
  for ($cc = 0; $cc < 8; $cc++) {
    $separa[(46 + $cc)] = $ZZBB[$cc]; 
  }


  $temporal_translated = 0;
  $temporal_translated = join '', @separa;
  $translated[$aa] =  $temporal_translated;
}
######### END OF SUB TRANSLATION


########## START OF SUB ARREGLAVALOR

sub ARREGLAVALOR {

  
  @arregla = 0;
  @arreglada = (" "," "," "," "," "," "," "," ");
    
  @arregla = @pasa_array;
  $long_arregla = @arregla;

  $posicion_punto = 0;
  $ff = 0;
  for ($ff = 0; $ff < $long_arregla; $ff++) {
    if ($arregla[$ff] eq ".") {
      $posicion_punto = $ff;
    }
  }
  
  ###decimales

  $arreglada[4] =  $arregla[($posicion_punto + 0)];  
  $arreglada[5] =  $arregla[($posicion_punto + 1)];
  $arreglada[6] =  $arregla[($posicion_punto + 2)];
  $arreglada[7] =  $arregla[($posicion_punto + 3)];

  #primer entero

  $arreglada[3] =  $arregla[($posicion_punto - 1)];
  

  #resto enteros

  if ($posicion_punto == 4) {
    $arreglada[2] =  $arregla[($posicion_punto - 2)];
    $arreglada[1] =  $arregla[($posicion_punto - 3)];
    $arreglada[0] =  $arregla[($posicion_punto - 4)];
  }
  if ($posicion_punto == 3){
    $arreglada[2] =  $arregla[($posicion_punto - 2)];
    $arreglada[1] =  $arregla[($posicion_punto - 3)];  
    $arreglada[0] =  " ";
  }
  if ($posicion_punto == 2){
    $arreglada[2] =  $arregla[($posicion_punto - 2)];
    $arreglada[1] =  " ";  
    $arreglada[0] =  " ";
  }
  if ($posicion_punto == 1){
    $arreglada[2] =  " ";
    $arreglada[1] =  " ";  
    $arreglada[0] =  " ";
  }
  @pasa_array = @arreglada;
}

########## END OF SUB ARREGLAVALOR

########## START OF SUB ARREGLAVALOR2

sub ARREGLAVALOR2 {

  
  @arregla2 = 0;
  @arreglada2 = (" "," "," "," "," "," "," "," "," "," "," ");
    
  @arregla2 = @pasa_array2;
  $long_arregla2 = @arregla2;

  $posicion_punto = 0;
  $ff = 0;
  for ($ff = 0; $ff < $long_arregla2; $ff++) {
    if ($arregla2[$ff] eq ".") {
      $posicion_punto = $ff;
    }
  }
  
  ###decimales

  $arreglada2[4] =  $arregla2[($posicion_punto + 0)];  
  $arreglada2[5] =  $arregla2[($posicion_punto + 1)];
  $arreglada2[6] =  $arregla2[($posicion_punto + 2)];
  $arreglada2[7] =  $arregla2[($posicion_punto + 3)];
  $arreglada2[8] =  $arregla2[($posicion_punto + 4)];
  $arreglada2[9] =  $arregla2[($posicion_punto + 5)];
  $arreglada2[10] =  $arregla2[($posicion_punto + 6)];

  #primer entero

  $arreglada2[3] =  $arregla2[($posicion_punto - 1)];
  

  #resto enteros

  if ($posicion_punto == 4) {
    $arreglada2[2] =  $arregla2[($posicion_punto - 2)];
    $arreglada2[1] =  $arregla2[($posicion_punto - 3)];
    $arreglada2[0] =  $arregla2[($posicion_punto - 4)];
  }
  if ($posicion_punto == 3){
    $arreglada2[2] =  $arregla2[($posicion_punto - 2)];
    $arreglada2[1] =  $arregla2[($posicion_punto - 3)];  
    $arreglada2[0] =  " ";
  }
  if ($posicion_punto == 2){
    $arreglada2[2] =  $arregla2[($posicion_punto - 2)];
    $arreglada2[1] =  " ";  
    $arreglada2[0] =  " ";
  }
  if ($posicion_punto == 1){
    $arreglada2[2] =  " ";
    $arreglada2[1] =  " ";  
    $arreglada2[0] =  " ";
  }
  @pasa_array2 = @arreglada2;
}

########## END OF SUB ARREGLAVALOR2

############# END OF CODE LINES ################
