2013-02-26 1 views
0

У меня есть филогенетическое дерево, которое я загружаю в BioPerl. Я хочу использовать пользовательскую функцию сортировки (далее «$ depth_sort»), чтобы упорядочить узлы по вертикали при печати дерева. Однако документально метод, используемый ниже выписывает дерева в том же порядке, что было прочитано в, фактически сортировки:Попытка пользовательского сортировки филогенетического дерева в BioPerl приводит к ошибке «неопределенного значения» или «ошибки без исправления»

use strict; 
use Bio::TreeIO; 

my $input = new Bio::TreeIO(-file=>"input.tree", -format=>'newick'); 
my $tree = $input->next_tree; 

my $depth_sort = sub { $a->depth <=> $b->depth }; 

#this is the way it is supposed to work: 
my $out = new Bio::TreeIO(
    -file  => ">sorted.tree", 
    -format => 'newick', 
    -order_by => $depth_sort 
); 
$out->write_tree($tree); 

Вместо этого, я могу вручную перебирать дерево, чтобы увидеть, что происходит. Если я делаю свои собственные рода локально, он работает, как ожидалось:

my $rnode = $tree->get_root_node; 
&printNode($rnode); 

sub printNode { 
    my $thisNode = shift; 

    #print the node identity and depth, just to keep track: 
    print "this is " . $thisNode->internal_id . 
      " with depth " . $thisNode->depth . "\n"; 

    if (! $thisNode->is_Leaf) { 
     my @children = sort $depth_sort $thisNode->each_Descendent(); 
     for my $otherNode (@children) { &printNode($otherNode); } 
    } 
} 

Но, если я прохожу пользовательскую сортировку в each_Descendent (способ вызова записи выше, как предполагается):

my @children = $thisNode->each_Descendent($depth_sort); 

Тогда он умирает с сообщением:

Невозможно вызвать метод «глубину» на неопределенное значение в treeFlipper.pl линии 7, строка 1.

я нашел другую нить здесь, что я думаю, что есть я на правильном пути, но я еще не решил ее еще: Perl sorting; dealing with $a, $b package globals across namespaces cleanly

Переход к методу прототипирования в первом ответе:

my $depth_sort = sub ($$) { 
    my ($a1,$b1) = @_; 
    return ($a1->depth <=> $b1->depth) }; 

дает я:

Невозможно вызвать метод "глубину" на неблагословленных ссылках на treeFlipper.pl линии 9, строка 1.

Но если проверить тип реф, что кажется правильным:

print ref($a1) . "\n"; 

дает

Bio::Tree::Node 

Когда я пытаюсь бессиловую благословляя ссылку (это, вероятно, страшная вещь, чтобы сделать):

bless $a1, 'Bio::Tree::Node'; 
bless $b1, 'Bio::Tree::Node'; 

я получаю:

не ссылка на ХЭШ /usr/local/share/perl/5.14.2/Bio/Tree/Node.pm линии 433, линия 1.

Другие методы в этом потоке (с помощью вызывающего абонента) дают мне такая же старая ошибка «неопределенного значения».

Это проблема с BioPerl, или (как я подозреваю), я все еще что-то пропустил? Благодаря!

Редактировать: используя Perl 5.14.2 на Ubuntu 12.04 LTS

+0

Что говорит ваша документация о пользовательском сортировке? Кажется, я не могу найти документацию по cpan. – TLP

+0

Я переустановил BioPerl, и теперь он работает, по крайней мере, вручную. Bio :: TreeIO :: write() по-прежнему игнорирует команду sort, но это явно проблема BioPerl, о которой я попрошу. – CAS

+0

http://search.cpan.org/~cjfields/BioPerl-1.6.901/Bio/TreeIO/newick.pm#new Это не прямой вызов, но функция Bio :: TreeIO :: new() должен передать дополнительные аргументы вместе с конструктором для конкретного формата: $obj = "Bio::TreeIO::$format"->new(@args); CAS

ответ

0

Там оказалось три части к этому:

  1. Функция сортировки действительно должен быть прототип и индексируются непосредственно или доступ через пакет вызова, как описано (например) в другой поток, с которым я связан.

  2. Почему это все еще не сработало после того, как функция сортировки является немного загадочной, но, вероятно, не воспроизводится. Это было решено путем переустановки BioPerl.

  3. И, наконец, оказывается, что текущая версия BioPerl (я имею 1.6.9) не полностью реализует параметр «order_by» - конструктор Bio :: TreeIO :: newick не устанавливает переданное значение, в ценности, как это должно. Тем не менее, я смог обойти это явно установив параметр после строительства:

    my $out = new Bio::TreeIO(
        -file  => ">sorted.tree", 
        -format => 'newick', 
    ); 
    $out->get_params->{'order_by'}=$depth_sort; 
    $out->write_tree($tree); 
    

Это работает, как ожидалось.

 Смежные вопросы

  • Нет связанных вопросов^_^