2016-12-15 2 views
1

Mit Bezug auf die Frage Datei Calculating the distance between atomic coordinates, wo der EingangBerechnung Entfernungen in PDB

ATOM 920 CA GLN A 203  39.292 -13.354 17.416 1.00 55.76   C 
ATOM 929 CA HIS A 204  38.546 -15.963 14.792 1.00 29.53   C 
ATOM 939 CA ASN A 205  39.443 -17.018 11.206 1.00 54.49   C 
ATOM 947 CA GLU A 206  41.454 -13.901 10.155 1.00 26.32   C 
ATOM 956 CA VAL A 207  43.664 -14.041 13.279 1.00 40.65   C 
. 
. 
. 

ATOM 963 CA GLU A 208  45.403 -17.443 13.188 1.00 40.25   C 

ist es an answer als

berichtet ist
use strict; 
use warnings; 

my @line; 
while (<>) { 
    push @line, $_;   # add line to buffer 
    next if @line < 2;   # skip unless buffer is full 
    print proc(@line), "\n"; # process and print 
    shift @line;    # remove used line 
} 

sub proc { 
    my @a = split ' ', shift; # line 1 
    my @b = split ' ', shift; # line 2 
    my $x = ($a[6]-$b[6]);  # calculate the diffs 
    my $y = ($a[7]-$b[7]); 
    my $z = ($a[8]-$b[8]); 
    my $dist = sprintf "%.1f",    # format the number 
        sqrt($x**2+$y**2+$z**2); # do the calculation 
    return "$a[3]-$b[3]\t$dist"; # return the string for printing 
} 

Die Ausgabe des obigen Codes ist der Abstand zwischen dem ersten CA zum zweiten und zweiten bis dritten und so weiter ...

So ändern Sie diesen Code, um den Abstand zwischen der ersten CA zum Rest der CAs (2, 3, ..) und von der zweiten CA zum Rest der CAs (3, 4, ..) usw. zu finden und nur zu drucken diejenigen, die weniger als 5 Angström sind? Ich fand, dass push @line, $_; Anweisung geändert werden sollte, um die Array-Größe zu erhöhen, aber nicht klar, wie das zu tun ist.

+0

Was ist Ihre erwartete Ausgabe? – ssr1012

+0

GLN-HIS "Abstandswert" -GLN ASN "Abstandswert" GLN-glu "Abstandswert" ... HIS-ASN "Abstandswert" HIS-GLU "Abstandswert" HIS-VAL „distance Wert " ... ASN-GLU" Distanzwert " ASN-VAL" Distanzwert " ... so weiter ... @ ssr1012 –

Antwort

3

Um die Paare zu erhalten, lesen Sie die Datei in ein Array, @data_array. Dann wiederhole die Einträge.

Update: Hinzugefügt Datei öffnen und @ data_array laden.

open my $fh, '<', 'atom_file.pdb' or die $!; 

my @data_array = <$fh>; 

close $fh or die $!; 

for my $i (0 .. $#data_array) { 
    for my $j ($i+1 .. $#data_array) { 
     process(@data_array[$i,$j]);  
    } 
} 
+0

Sollte ich diese Zeilen anstelle von" push @line, $ _; "andere Teile des Codes behalten, wie er ist? Bitte geben Sie den vollständigen Code nach dem Hinzufügen dieser Zeilen ein. –

+1

@pradeep pant Ich habe den Code vor den 2 for loops hinzugefügt. sub 'process' ist Ihr sub' proc' (Sie müssen Ihre 'proc' Sub bearbeiten, um entweder die Abstände auszudrucken oder eine passende Zeichenkette zum Ausdrucken zurückzugeben) –

3

kann dies versuchen:

use strict; 
use warnings; 

my @alllines =(); 
while(<DATA>) { push(@alllines, $_); } 

#Each Current line 
for(my $i=0; $i<=$#alllines+1; $i++) 
{ 
    #Each Next line 
    for(my $j=$i+1; $j<=$#alllines; $j++) 
    { 
     if($alllines[$i]) 
     { 
      #Split the line into tab delimits 
      my ($line1_tb_1,$line1_tb_2,$line1_tb_3) = split /\t/, $alllines[$i]; 
      print "Main_Line: $line1_tb_1\t$line1_tb_2\t$line1_tb_3"; 
      if($alllines[$j]) 
      { 
       #Split the line into tab delimits 
       my ($line_nxt_tb1,$line_nxt_tb2,$line_nxt_tb3) = split /\t/, $alllines[$j]; 

       print "Next_Line: $line_nxt_tb1\t$line_nxt_tb2\t$line_nxt_tb3"; 

       #Do it your coding/regex here 
      } 
     } 
     #system 'pause'; Testing Purpose!!! 
    } 
} 

__DATA__ 
tab1 123 456 
tab2 789 012 
tab3 345 678 
tab4 901 234 
tab5 567 890 

Ich hoffe, dies wird Ihnen helfen.