3

GFF3 ファイル名と範囲 (つまり、100000 .. 2000000) を取得する Perl 関数を書きたいと思います。この範囲で見つかった遺伝子のすべての名前/アクセスを含む配列への参照を返します。

bioperl を使うのは理にかなっていると思いますが、私はそれを使った経験がほとんどありません。自分で GFF3 を解析するスクリプトを作成できますが、bioperl (または別のパッケージ) の使用がそれほど複雑でない場合は、それらのコードを再利用したいと思います。

4

3 に答える 3

3
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();

免責事項: 単純な実装です。私はちょうどそれを強打しました、それはテストがありませんでした。私はそれがコンパイルされることさえ保証しません。

于 2010-09-08T20:19:43.857 に答える
2

BioPerlおそらくBio::Tools::GFFモジュールを使用して、これを使用したいと思います。

BioPerl メーリング リストで質問してください。とてもフレンドリーで、加入者は非常に知識が豊富です。彼らは間違いなくあなたを助けることができます. 回答が得られたら (ここで最初に回答が得られなかった場合)、ここで自分の質問に答えて回答することをお勧めします。

于 2010-09-08T16:00:31.350 に答える
0

次の関数は、ターゲットと範囲のハッシュを取得し、いずれかの範囲と重複するすべてのターゲットを反復処理する関数を返します。ターゲットは、参照の配列への参照である必要があります。

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;
        };
}
于 2010-09-08T22:13:40.167 に答える