monkfan has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

Is there a way to create object $in from an array and in plain format instead of filehandle (DATA or FILE) in fasta format.
#!/usr/bin/perl -w use strict; use Bio::AlignIO; # How can I change this method call so that instead of FH # it takes data from an array, like this: # @array = qw /AAAAAAAAAAAAAAA AAAAAAAGGAAACCA/; my $in = Bio::AlignIO->new(-fh => \*DATA, -format => 'fasta'); while ( my $aln = $in->next_aln() ) { print "IDENTITY : ", $aln->percentage_identity, "\n"; print "CONSENSUS: ", $aln->consensus_string(28), "\n"; } __DATA__ >Seq1 AAAAAAAAAAAAAAA >Seq2 AAAAAAAGGAAACCA
Regards,
Edward

Replies are listed 'Best First'.
Re: Converting Filehandle to Array call in Object Creation
by ikegami (Patriarch) on Apr 15, 2005 at 05:31 UTC

    From looking at the source, I think this is equivalent:

    use Bio::LocatableSeq (); use Bio::SimpleAlign (); my $aln = Bio::SimpleAlign->new(); foreach (qw/ AAAAAAAAAAAAAAA AAAAAAAGGAAACCA /) { $aln->add_seq( Bio::LocatableSeq->new( '-seq' => $_, '-start' => 1, '-end' => length($_), ) ); } print("IDENTITY : ", $aln->percentage_identity, "\n"); print("CONSENSUS: ", $aln->consensus_string(28), "\n");

    You can optionally add
    '-display_id'  => 'Seq'.++$seq_id,
    as an argument to the Bio::LocatableSeq constructor.

    Warning: This is untested code written using unfamiliar modules.

Re: Converting Filehandle to Array call in Object Creation
by davidrw (Prior) on Apr 15, 2005 at 13:39 UTC
    I think that IO::Scalar might be what you're looking for:
    use IO::Scalar; my $data = <<EOF; AAAAAAAAAAAAAAA AAAAAAAGGAAACCA EOF my $SH = new IO::Scalar \$data; my $in = Bio::AlignIO->new(-fh => $SH, -format => 'fasta');
      The requirements were to start with an array. I suppose you could create $data by joining the contents of the array, but I don't think that's enough because what I said to holli applies to you too.
        Ah. y, i was concentrating more on the variable to filehandle issue rather than the actual data format.. Could still join it, though--just need an extra step to the join.. something like:
        my @data = qw/AAAAAAAAAAAAAAA AAAAAAAGGAAACCA/; my $ct = 0; my $data = join '', map { sprintf ">Seq%d\n%s\n", ++$ct, $_ } @data; my $SH = new IO::Scalar \$data;
Re: Converting Filehandle to Array call in Object Creation
by holli (Abbot) on Apr 15, 2005 at 10:24 UTC
    You can do that by using a tied Filehandle. Create this module:
    package Tie::Handle::FromArray; use strict; use warnings; sub new { my $pkg = shift; my $handle = \do {local *HANDLE}; tie *{$handle}, $pkg, @_; return $handle; } sub TIEHANDLE($;$) { my $pkg = shift; my $ref = shift || []; bless( $ref, $pkg ); } sub READLINE { return shift @{+shift} } "this is a false statement.";
    and alter your script:
    my $fh = Tie::Handle::FromArray->new( ["AAAAAAAAAAAAAAA", "AAAAAAAGGAA +ACCA"] ); my $in = Bio::AlignIO->new(-fh => $fh, -format => 'fasta');


    holli, /regexed monk/
      Your tied class doesn't add ">Seq1", ">Seq2", etc to the stream. From what I saw, leaving those out causes the whole array to be treated as a single sequence (namely "AAAAAAAAAAAAAAAAAAAAAAGGAAACCA").
        I must admit I don't get what you're saying.
        use strict; use warnings; use Tie::Handle::FromArray; my $fh = new Tie::Handle::FromArray ( ["a","b"] ); while (<$fh>) { print "$_*"; }
        prints
        a*b*
        just as i would expect. can you clarify?


        holli, /regexed monk/