2013-12-23 52 views
1

我從本網站下面得到了這個腳本。
通過原子座標計算原子間的距離

use strict; 
use warnings; 

open(OUTPUT,">/home/guest/Desktop/test.txt") or die ("couldn't write the file"); 
my @line; 
for (<>) { 
    push @line, $_;    
    next if (@line)<2; 
    print OUTPUT distance(@line), "\n"; 
} 
sub distance { 
    my @a = split ' ',shift; 
    my @b = split ' ',; 
    my $x = ($a[6]-$b[6]);  
    my $y = ($a[7]-$b[7]); 
    my $z = ($a[8]-$b[8]); 
    my $dist = sprintf "%.1f",sqrt($x**2+$y**2+$z**2); 
    return "$a[1] to $b[1] |$a[11]-$b[11]| Distance-\t$dist"; 
} 

我用這個腳本來識別原子之間的距離。我只能用一個原子實現。

INPUT 

HETATM 1 N MSE A 1  16.272 16.789 53.256 1.00 31.95   N 
HETATM 2 CA MSE A 1  15.408 15.939 52.384 1.00 30.64   C 
HETATM 3 C MSE A 1  13.919 16.266 52.544 1.00 27.80   C 
HETATM 4 O MSE A 1  13.393 16.321 53.659 1.00 26.16   O 

OUTPUT 

1 to 2 |N-C| Distance- 1.5 
1 to 3 |N-C| Distance- 2.5 
1 to 4 |N-O| Distance- 2.9 

期望的輸出

1至2 | N-C |距離 - 1.5
1至3 | N-C |距離 - 2.5
1至4 | N-O |距離 - 2.9
2對1 | N-C |距離 - 1.5
2至3 | N-C |距離 - 2.5
2至4 | N-O |距離 - 2.9
3對1 | N-C |距離 - 1.5
3至2 | N-C |距離 - 2.5
3至4 | N-O |距離 - 2.9
4對1 | N-C |距離 - 1.5
4至2 | N-C |距離 - 2.5
4至3 | N-O |距離 - 2.9

請幫我

回答

3

my @b = split ' ',; 

拆分$_可變進陣列@b,當你想要什麼@_陣列的頂部。

它也看起來像你想計算的每對原子之間的距離,你需要一個雙循環來實現。

如果你寫了一個名爲distance子程序,那麼它是最好的,如果它返回一個距離,而不是調用代碼恰好想要一些任意字符串。

該程序似乎是做你想做的,並且使用printf作爲輸出。

use strict; 
use warnings; 

open my $out, '>', '/home/guest/Desktop/test.txt' or die "Couldn't open output file: $!"; 
my @data = map [ split ], grep /\S/, <>; 

for my $i (0 .. $#data) { 
    for my $j (0 .. $#data) { 

    next if $i == $j; 

    my @coords_i = @{$data[$i]}[6,7,8]; 
    my @coords_j = @{$data[$j]}[6,7,8]; 

    printf $out "%s to %s |%s-%s| Distance-%.3f\n", 
     $data[$i][1], $data[$j][1], 
     $data[$i][11], $data[$j][11], 
     distance(\@coords_i, \@coords_j); 
    } 
} 

sub distance { 
    my ($aa, $bb) = @_; 
    my ($x, $y, $z) = map { $aa->[$_] - $bb->[$_] } 0 .. $#$aa; 
    return sqrt($x * $x + $y * $y + $z * $z); 
} 

輸出

1 to 2 |N-C| Distance-1.493 
1 to 3 |N-C| Distance-2.513 
1 to 4 |N-O| Distance-2.944 
2 to 1 |C-N| Distance-1.493 
2 to 3 |C-C| Distance-1.533 
2 to 4 |C-O| Distance-2.415 
3 to 1 |C-N| Distance-2.513 
3 to 2 |C-C| Distance-1.533 
3 to 4 |C-O| Distance-1.234 
4 to 1 |O-N| Distance-2.944 
4 to 2 |O-C| Distance-2.415 
4 to 3 |O-C| Distance-1.234 
+0

非常感謝你! – user3032425

1

您有4個文件中的行,所以你的循環將有4次迭代(並且由於列表的大小爲1仍然將跳過第一個)。

如果要匹配每個2個元素,則需要一個嵌套循環,該循環將運行n^2迭代,給定n行的輸入。只要切換主循環進入這個

for (<>) { 
    push @line, $_;    
} 
for $a (@line) { 
    for $b (@line) { 
      next if ($a eq $b); 
      print OUTPUT distance(@line), "\n"; 
    } 
} 
+0

對不起它的示值誤差.. – user3032425

+0

@ user3032425,關心該說些什麼錯誤?我工作得很好 – Leeor