这两个脚本是相关连的。可以执行脚本1后再执行脚本2。
第三个脚本将脚本2生成的某文件变为对称矩阵。
文件名神马的当然得改了,程序友好度不佳
脚本1:
dist_ident_1.pl
#!perl -w
# 这是以前写的代码,tab不改空格了……
#貌似运行成功
#分开Nei 1972或1978的数据的 genetic distance 与 genetic identity 表
#数据是Popgene32算出的
use strict;
my $rst = 'pop57'; # 某文件,后缀'rst'就不用改了
#$rst =~ s/\..*$//;
genetic_nei($rst);
###================================================
# 子程序
###================================================
# 分开Nei 1972和1978的数据
sub genetic_nei {
foreach (@_) {
my $in = $_;
my $out = "$in" . "_1972.txt";
my $outi = "$in" . "_1978.txt";
open IN, "<", "$in" . ".rst" or die "Can't open '$in': $!";
open OUT, ">", "$out" or die "Can't write to '$out': $!";
open OUTI, ">", "$outi" or die "Can't write to '$outi': $!";
my $n = 0;
my $m = undef;
while(<IN>) {
print OUT "$1\n\n" if /(See Nei.*292)/;
print OUTI "$1\n\n" if /(See Nei.*590)/;
if(/^\d+/) {
s/^\d+\s+//; # 去掉开头的编号
s/ *$//; # 去掉末尾的空格
s/ +/\t/g; # 把多个空格换成一个制表符
$m = (split) unless (defined $m);
if($n < $m) {
print OUT;
} else {
print OUTI;
}
$n++;
}
}
close IN;
close OUT;
close OUTI;
divide($out, $outi);
}
}
###================================================
# 分开两组数据
sub divide {
foreach ( @_ ) {
my $in = $_;
my $out = $in;
my $outi = $in;
$out =~ s/^/identity_/; # 特征值
$outi =~ s/^/dist_/; # 遗传距离
open IN, "<$in" or die "Can't open '$in': $!";
open OUT, ">", "$out" or die "Can't write to '$out': $!";
open OUTI, ">", "$outi" or die "Can't write to '$outi': $!";
while(<IN>) {
if (/\*{4}/) {
my $m = $`; # 遗传距离
my $n = $'; # 特征值
print OUTI "$m" . "0\n"; # 把“****”替换为“0”
$m =~ s/[^\s]+/1/g; # 把遗传距离表替换为“1”
print OUT "$m" . "1" ."$n"; # 之前的“****”以“1”代替
}
}
close IN;
close OUT;
close OUTI;
}
}
脚本2:
dist_ident_2.pl
#!perl -w
#貌似运行成功
#Nei 1972和1978的数据最大最小值
#数据是Popgene32算出的
use strict;
# 从前是 @ARGV,今 @hehe
my @hehe = qw(pop57);
my @dist;
my @ident;
my ($d_1972, $d_1978, $i_1972, $i_1978);
foreach ( @hehe ) {
$d_1972 = "dist_" . $_ . "_1972.txt";
$d_1978 = "dist_" . $_ . "_1978.txt";
$i_1972 = "identity_" . $_ . "_1972.txt";
$i_1978 = "identity_" . $_ . "_1978.txt";
push @dist, $d_1972;
push @dist, $d_1978;
push @ident, $i_1972;
push @ident, $i_1978;
}
max_dist(@dist);
min_ident(@ident);
print "Done!\n";
#####
sub max {
my $max_so_far = shift @_;
foreach ( @_ ) {
if ($_ > $max_so_far) {
$max_so_far = $_;
}
}
$max_so_far;
}
#####
sub min {
my $min_so_far = shift @_;
foreach ( @_ ) {
if ($_ < $min_so_far) {
$min_so_far = $_;
}
}
$min_so_far;
}
#####
# 求数据的最大值或最小值
sub max_dist {
foreach ( @_ ) {
my $in = $_;
my $out = $in;
my @pops;
open IN, "<$in" or die "Can't open '$in': $!";
$out =~ s/\.txt$//;
open OUT, '>', "$out" . "_结果.txt" or die "Can't write to '_结果.txt': $!";
my $try = 0;
my $i;
while(<IN>) {
my @nums = split /\s+/, $_;
my $num = @nums;
@pops = (1 .. $num);
$try = max(@nums, $try);
}
print OUT "\n最大值为:$try\n";
close IN;
open IN, "<$in" or die "Can't open '$in': $!"; # 需要重新打开,目前不知道更好的办法
while(<IN>) {
$i++; # 第几行
my $j;
foreach ( split /\s+/, $_ ) {
$j++;
if ($_ == $try) {
print OUT $pops[$i - 1], "\t", $pops[$j - 1], "\n"; # 对应的各个坐标
}
}
}
}
}
sub min_ident {
foreach ( @_ ) {
my $in = $_;
my $out = $in;
my @pops;
open IN, "<$in" or die "Can't open '$in': $!";
$out =~ s/\.txt$//;
open OUT, '>', "$out" . "_结果.txt" or die "Can't write to '_结果.txt': $!";
my $try = 1;
my $i;
while(<IN>) {
my @nums = split /\s+/, $_;
my $num = @nums;
@pops = (1 .. $num);
$try = min(@nums, $try);
}
print OUT "\n最小值为:$try\n";
close IN;
open IN, "<$in" or die "Can't open '$in': $!"; # 需要重新打开,目前不知道更好的办法
while(<IN>) {
$i++; # 第几行
my $j;
foreach ( split /\s+/, $_ ) {
$j++;
if ($_ == $try) {
print OUT $pops[$i - 1], "\t", $pops[$j - 1], "\n"; # 对应的各个坐标
}
}
}
}
}
脚本3:
tri2square.pl
#!perl
use strict;
use warnings;
# 三角阵生对称矩阵
my $in = 'dist_pop57_1978.txt';
my $out = 'square_dist_pop57_1978.txt';
my %dist;
open IN, '<', $in or die "Can't open '$in': $!";
open OUT, '>', $out or die "Can't write to '$out': $!";
my $m = 0;
while (<IN>) {
$m++;
my $n = 1;
for my $x (split) {
$dist{$m}{$n} = $dist{$n}{$m} = $x;
$n++;
}
}
close IN;
for my $i (1 .. $m) {
for my $j (1 .. ($m-1)) {
print OUT "$dist{$i}{$j}\t";
}
print OUT "$dist{$i}{$m}\n";
}
close OUT;
print "Done!\n";