GFF3 ファイル名と範囲 (つまり、100000 .. 2000000) を取得する Perl 関数を書きたいと思います。この範囲で見つかった遺伝子のすべての名前/アクセスを含む配列への参照を返します。
bioperl を使うのは理にかなっていると思いますが、私はそれを使った経験がほとんどありません。自分で GFF3 を解析するスクリプトを作成できますが、bioperl (または別のパッケージ) の使用がそれほど複雑でない場合は、それらのコードを再利用したいと思います。
use Bio::Tools::GFF;
my $range_start = 100000;
my $range_end = 200000;
my @features_in_range = ( );
my $gffio = Bio::Tools::GFF->new(-file => $gff_file, -gff_version => 3);
while (my $feature = $gffio->next_feature()) {
## What about features that are not contained within the coordinate range but
## do overlap it? Such features won't be caught by this check.
if (
($feature->start() >= $range_start)
&&
($feature->end() <= $range_end)
) {
push @features_in_range, $feature;
}
}
$gffio->close();
免責事項: 単純な実装です。私はちょうどそれを強打しました、それはテストがありませんでした。私はそれがコンパイルされることさえ保証しません。
BioPerl
おそらくBio::Tools::GFF
モジュールを使用して、これを使用したいと思います。
BioPerl メーリング リストで質問してください。とてもフレンドリーで、加入者は非常に知識が豊富です。彼らは間違いなくあなたを助けることができます. 回答が得られたら (ここで最初に回答が得られなかった場合)、ここで自分の質問に答えて回答することをお勧めします。
次の関数は、ターゲットと範囲のハッシュを取得し、いずれかの範囲と重複するすべてのターゲットを反復処理する関数を返します。ターゲットは、参照の配列への参照である必要があります。
my $targets =
[
[
$start,
$end,
],
...,
]
範囲は、ハッシュの配列への参照である必要があります。
my $ranges =
[
{
seqname => $seqname,
source => $source,
feature => $feature,
start => $start,
end => $end,
score => $score,
strand => $strand,
frame => $frame,
attribute => $attribute,
},
...,
]
もちろん、ターゲットを 1 つだけ通過させることもできます。
my $brs_iterator
= binary_range_search( targets => $targets, ranges => $ranges );
while ( my $gff_line = $brs_iterator->() ) {
# do stuff
}
sub binary_range_search {
my %options = @_;
my $targets = $options{targets} || croak 'Need a targets parameter';
my $ranges = $options{ranges} || croak 'Need a ranges parameter';
my ( $low, $high ) = ( 0, $#{$ranges} );
my @iterators = ();
TARGET:
for my $range (@$targets) {
RANGE_CHECK:
while ( $low <= $high ) {
my $try = int( ( $low + $high ) / 2 );
$low = $try + 1, next RANGE_CHECK
if $ranges->[$try]{end} < $range->[0];
$high = $try - 1, next RANGE_CHECK
if $ranges->[$try]{start} > $range->[1];
my ( $down, $up ) = ($try) x 2;
my %seen = ();
my $brs_iterator = sub {
if ( $ranges->[ $up + 1 ]{end} >= $range->[0]
and $ranges->[ $up + 1 ]{start} <= $range->[1]
and !exists $seen{ $up + 1 } )
{
$seen{ $up + 1 } = undef;
return $ranges->[ ++$up ];
}
elsif ( $ranges->[ $down - 1 ]{end} >= $range->[0]
and $ranges->[ $down - 1 ]{start} <= $range->[1]
and !exists $seen{ $down - 1 }
and $down > 0 )
{
$seen{ $down - 1 } = undef;
return $ranges->[ --$down ];
}
elsif ( !exists $seen{$try} ) {
$seen{$try} = undef;
return $ranges->[$try];
}
else {
return;
}
};
push @iterators, $brs_iterator;
next TARGET;
}
}
# In scalar context return master iterator that iterates over the list of range iterators.
# In list context returns a list of range iterators.
return wantarray
? @iterators
: sub {
while (@iterators) {
if ( my $range = $iterators[0]->() ) {
return $range;
}
shift @iterators;
}
return;
};
}