У меня есть филогенетическое дерево, которое я загружаю в 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
Что говорит ваша документация о пользовательском сортировке? Кажется, я не могу найти документацию по cpan. – TLP
Я переустановил BioPerl, и теперь он работает, по крайней мере, вручную. Bio :: TreeIO :: write() по-прежнему игнорирует команду sort, но это явно проблема BioPerl, о которой я попрошу. – CAS
http://search.cpan.org/~cjfields/BioPerl-1.6.901/Bio/TreeIO/newick.pm#new Это не прямой вызов, но функция Bio :: TreeIO :: new() должен передать дополнительные аргументы вместе с конструктором для конкретного формата:
$obj = "Bio::TreeIO::$format"->new(@args);
– CAS