这是我的程序,我想在不同的时间计算两个原子之间的欧氏距离。所以我可以修改这个程序使它成为可能。我的输入是
1 I -6.2528 -0.8879 0.3208 I 1 LIG1 -0.0425
2 O -0.1927 0.3708 -0.4256 O.3 1 LIG1 -0.4750
3 N 2.7475 3.2931 0.6111 N.3 1 LIG1 -0.2164
4 C 0.6554 0.0834 0.6881 C.3 1 LIG1 0.1896
5 C 1.3107 1.3881 1.1695 C.3 1 LIG1 0.0670
6 C 1.6435 -0.9764 0.2598 C.ar 1 LIG1 0.0172
7 C 2.1448 2.0726 0.0863 C.3 1 LIG1 0.0928
8 C -1.5245 0.1089 -0.2623 C.ar 1 LIG1 0.1349
9 C 2.1274 -1.8960 1.1905 C.ar 1 LIG1 -0.0008
10 C 2.0723 -1.0350 -1.0663 C.ar 1 LIG1 -0.0008
11 C -2.4708 1.1273 -0.3768 C.ar 1 LIG1 0.0125
12 C 3.0398 -2.8742 0.7949 C.ar 1 LIG1 -0.0002
13 C 2.9846 -2.0133 -1.4618 C.ar 1 LIG1 -0.0002
14 C -1.9331 -1.1945 0.0206 C.ar 1 LIG1 0.0370
15 C 3.4684 -2.9327 -0.5314 C.ar 1 LIG1 -0.0000
16 C 3.5783 3.9360 -0.3969 C.3 1 LIG1 0.1075
这是我的程序
#!/usr/bin/perl -w
use strict;
my $num = 0;
my @arrayx;
my @arrayy;
my @arrayz;
while (<>) {
# remove new line char
chomp;
# Find x, y, z coordinates and store in separate arrays
if (/^ATOM/) {
my @line = $_ =~ m/^(.....).(.....).(....).(...)..(....)....(........)(........) (........)/;
my $x = $line[5];
$arrayx[$num] = $x;
my $y = $line[6];
$arrayy[$num] = $y;
my $z = $line[7];
$arrayz[$num] = $z;
++$num;
}
}
# Calculate distance between all atom coordinates
for my $i ( 0 .. $num ) {
for my $j ( $i + 1 .. $num ) {
# skip if j array element does not exist
unless ( defined( $arrayx[$j] )
&& defined( $arrayy[$j] )
&& defined( $arrayz[$j] ) )
{
print "Skipping i:$i j:$j\n";
sleep(1);
next;
}
my $dist =
sqrt( ( $arrayx[$i] - $arrayx[$j] )**2 +
( $arrayy[$i] - $arrayy[$j] )**2 +
( $arrayz[$i] - $arrayz[$j] )**2 );
print "$dist\n";
}
}
答案 0 :(得分:1)
您发布了一些示例数据,但实际上并没有告诉我们它的含义。我怀疑第2,第3和第4列分别是指x,y和z,但你应该确认这一点。
如果是这种情况,那么以下是您的代码的清理版本。也许它会对你有所帮助:
#!/usr/bin/perl -w
use strict;
my @data;
while (<DATA>) {
chomp;
# Find x, y, z coordinates and store in separate arrays
my @line = split;
push @data, {
x => $line[2],
y => $line[3],
z => $line[4],
name => $line[5],
};
}
# Calculate distance between all atom coordinates
for my $i ( 0 .. $#data ) {
for my $j ( $i + 1 .. $#data ) {
my $dist =
sqrt( ( $data[$i]{x} - $data[$j]{x} )**2 +
( $data[$i]{y} - $data[$j]{y} )**2 +
( $data[$i]{z} - $data[$j]{z} )**2 );
printf "%-6s %-6s %f\n", $data[$i]{name}, $data[$j]{name}, $dist;
}
}
__DATA__
1 I -6.2528 -0.8879 0.3208 I 1 LIG1 -0.0425
2 O -0.1927 0.3708 -0.4256 O.3 1 LIG1 -0.4750
3 N 2.7475 3.2931 0.6111 N.3 1 LIG1 -0.2164
4 C 0.6554 0.0834 0.6881 C.3 1 LIG1 0.1896
5 C 1.3107 1.3881 1.1695 C.3 1 LIG1 0.0670
6 C 1.6435 -0.9764 0.2598 C.ar 1 LIG1 0.0172
7 C 2.1448 2.0726 0.0863 C.3 1 LIG1 0.0928
8 C -1.5245 0.1089 -0.2623 C.ar 1 LIG1 0.1349
9 C 2.1274 -1.8960 1.1905 C.ar 1 LIG1 -0.0008
10 C 2.0723 -1.0350 -1.0663 C.ar 1 LIG1 -0.0008
11 C -2.4708 1.1273 -0.3768 C.ar 1 LIG1 0.0125
12 C 3.0398 -2.8742 0.7949 C.ar 1 LIG1 -0.0002
13 C 2.9846 -2.0133 -1.4618 C.ar 1 LIG1 -0.0002
14 C -1.9331 -1.1945 0.0206 C.ar 1 LIG1 0.0370
15 C 3.4684 -2.9327 -0.5314 C.ar 1 LIG1 -0.0000
16 C 3.5783 3.9360 -0.3969 C.3 1 LIG1 0.1075
输出:
I O.3 6.234280
I N.3 9.928264
I C.3 6.985811
I C.3 7.943991
I C.ar 7.897032
I C.3 8.907258
I C.ar 4.867282
I C.ar 8.485305
I C.ar 8.441148
I C.ar 4.341797
I C.ar 9.514335
I C.ar 9.474901
I C.ar 4.340960
I C.ar 9.970415
I C.3 10.974317
O.3 N.3 4.273097
O.3 C.3 1.429056
O.3 C.3 2.416496
O.3 C.ar 2.378309
....
答案 1 :(得分:0)
你不清楚问题是什么。目前尚不清楚会发生什么以及应该发生什么。尤其应该发生什么。我不知道mol2格式,甚至更少知道如何在不同时间计算欧氏距离。
但是:您的评论意味着问题在于
行my @line = $_ =~ m/^(.....).(.....).(....).(...)..(....)....(........ (........) (........)/;
我不完全确定你在这里尝试做什么。您是否尝试将粘贴文本文件的一行(mol2?)的字段放入数组@line
?如果是这样,请尝试
my @line = split ' ', $_;
代替。这将删除任何前导空格,然后将字符串拆分为任意数量的空格。因此,如果您以这种方式拆分第一个示例行,最后将以$line[2]
== -6.2528,$line[3]
== -0.8879,$line[4]
== 0.3208结束
假设这些是您追求的数字。