diff --git a/.gitignore b/.gitignore index b4a2e2e..cc50e9c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ 05.reduce_redundancy/* 05.orthology_inference/* 06.phylogeny_reconstruction/* +06.phylogenetic_analysis/* 06.gene_trees/* 10.plastid/* 98.results/* diff --git a/99.scripts/ticr/bucky.pl b/99.scripts/miscs/bucky.pl similarity index 100% rename from 99.scripts/ticr/bucky.pl rename to 99.scripts/miscs/bucky.pl diff --git a/99.scripts/workflow/phylogeny_reconstruction/mbblock.txt b/99.scripts/miscs/mbblock.txt similarity index 100% rename from 99.scripts/workflow/phylogeny_reconstruction/mbblock.txt rename to 99.scripts/miscs/mbblock.txt diff --git a/99.scripts/miscs/mrbayes.sh b/99.scripts/miscs/mrbayes.sh new file mode 100644 index 0000000..318068d --- /dev/null +++ b/99.scripts/miscs/mrbayes.sh @@ -0,0 +1,20 @@ +#! /bin/bash +set -e +SCRIPTS=${SCRIPTS:-"$PROJECTHOME/99.scripts"} + +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +in_fasta=$(readlink -f "$1") +out_nex=$2 + +# Convert fasta to nexus +out_dir=$(dirname "$out_nex") +mkdir -p "$out_dir" +seqmagick convert --output-format nexus --alphabet dna --input-format fasta "$in_fasta" "$out_nex" +# append MrBayes block to nexus file +cat "$SCRIPTS"/miscs/mbblock.txt >>"$out_nex" +# Run MrBayes +mb "$out_nex" >"${out_dir}"/mrbayes.log 2>&1 diff --git a/99.scripts/miscs/raxml.sh b/99.scripts/miscs/raxml.sh new file mode 100644 index 0000000..a6a5ab0 --- /dev/null +++ b/99.scripts/miscs/raxml.sh @@ -0,0 +1,20 @@ +#! /bin/bash +set -e +if [ "$#" -ne 4 ]; then + echo "Usage: $0 " + echo "Run modeltest-ng and raxml-ng on a given alignment" + exit 1 +fi + +aln=$(readlink -f "$1") +out=$2 +threads=$3 +outgroup=$4 +outdir=$(dirname "$out") +mkdir -p "$outdir" +# run modeltest-ng +modeltest-ng -p "$threads" -r 12345 --force -i "$aln" -d nt -t ml -o "$out".modeltest +# run raxml-ng +cmd=$(grep "raxml-ng" "$out".modeltest.out | tail -n 1 | sed 's/> //') +params="--all --bs-trees 1000 --outgroup $outgroup --redo --threads $threads --seed 12345 --prefix $out" +bash -c "$cmd $params" >/dev/null diff --git a/99.scripts/ticr/mb.pl b/99.scripts/ticr/mb.pl deleted file mode 100755 index 70aedbc..0000000 --- a/99.scripts/ticr/mb.pl +++ /dev/null @@ -1,1102 +0,0 @@ -#!/usr/bin/perl -use strict; -use warnings; -use POSIX; -use IO::Select; -use IO::Socket; -use Digest::MD5; -use Getopt::Long; -use Cwd qw(abs_path); -use Fcntl qw(:flock); -use File::Path qw(remove_tree); -use Time::HiRes qw(time usleep); - -my $os_name = $^O; - -# Turn on autoflush -$|++; - -# Maximum number of threads to use -my $max_forks; - -# Server port -my $port = 10002; - -# Stores executing machine hostnames -my @machines; -my %machines; - -# Path to text file containing computers to run on -my $machine_file_path; - -# MrBayes block which will be used for each run -my $mb_block; - -# Where this script is located -my $script_path = abs_path($0); - -# Directory script was called from -my $init_dir = abs_path("."); - -# Where the script was called from -my $initial_directory = $ENV{PWD}; - -# Allow for reusing info from an old run -my $input_is_dir = 0; - -# How the script was called -my $invocation = "perl mb.pl @ARGV"; - -# Name of output directory -my $project_name = "mb-".int(time()); -#my $project_name = "mb-dir"; - -# Read commandline settings -GetOptions( - #"no-forks" => \$no_forks, - "mb-block|m:s" => \$mb_block, - "machine-file:s" => \$machine_file_path, - "check|c:f" => \&check_nonconvergent, - "remove|r:f" => \&remove_nonconvergent, - "out-dir|o=s" => \$project_name, - "n-threads|T" => \$max_forks, - "port=i" => \$port, - "server-ip:s" => \&client, # for internal usage only - "help|h" => sub { print &help; exit(0); }, - "usage" => sub { print &usage; exit(0); }, -); - - -# Get paths to required executables -my $mb = check_path_for_exec("mb"); - -my $archive = shift(@ARGV); - -# Some error checking -die "You must specify an archive file.\n\n", &usage if (!defined($archive)); -die "Could not locate '$archive', perhaps you made a typo.\n" if (!-e $archive); -die "You specified a MrBayes run archive instead of an MDL gene archive.\n" if ($archive =~ /\.mb\.tar$/); -die "Could not locate '$machine_file_path'.\n" if (defined($machine_file_path) && !-e $machine_file_path); -die "You must specify a file containing a valid MrBayes block which will be appended to each gene.\n\n", &usage if (!defined($mb_block)); -die "Could not locate '$mb_block', perhaps you made a typo.\n\n" if (!-e $mb_block); - -# Input is a previous run directory, reuse information -$input_is_dir++ if (-d $archive); - -# Determine which machines we will run the analyses on -if (defined($machine_file_path)) { - - # Get list of machines - print "Fetching machine names listed in '$machine_file_path'...\n"; - open(my $machine_file, '<', $machine_file_path); - chomp(@machines = <$machine_file>); - close($machine_file); - - # Check that we can connect to specified machines - foreach my $index (0 .. $#machines) { - my $machine = $machines[$index]; - print " Testing connection to: $machine...\n"; - - # Attempt to ssh onto machine with a five second timeout - my $ssh_test = `timeout 5 ssh -v $machine exit 2>&1`; - - # Look for machine's IP in test connection - my $machine_ip; - if ($ssh_test =~ /Connecting to \S+ \[(\S+)\] port \d+\./s) { - $machine_ip = $1; - } - - # Could connect but passwordless login not enabled - if ($ssh_test =~ /Are you sure you want to continue connecting \(yes\/no\)/s) { - print " Connection to $machine failed, removing from list of useable machines (passwordless login not enabled).\n"; - splice(@machines, $index, 1); - } - # Successful connection - elsif (defined($machine_ip)) { - print " Connection to $machine [$machine_ip] successful.\n"; - $machines{$machine} = $machine_ip; - } - # Unsuccessful connection - else { - print " Connection to $machine failed, removing from list of useable machines.\n"; - splice(@machines, $index, 1); - } - } -} - -print "\nScript was called as follows:\n$invocation\n"; - -# Load MrBayes block into memory -open(my $mb_block_file, "<", $mb_block) or die "Could not open '$mb_block': $!.\n"; -my @mb_block = <$mb_block_file>; -close($mb_block_file); - -my $archive_root; -my $archive_root_no_ext; -if (!$input_is_dir) { - - # Clean run with no prior output - - # Extract name information from input file - ($archive_root = $archive) =~ s/.*\/(.*)/$1/; - ($archive_root_no_ext = $archive) =~ s/(.*\/)?(.*)(\.tar\.gz)|(\.tgz)/$2/; - - # Initialize working directory - # Remove conditional eventually - mkdir($project_name) || die "Could not create '$project_name'$!.\n" if (!-e $project_name); - - my $archive_abs_path = abs_path($archive); - # Remove conditional eventually - run_cmd("ln -s $archive_abs_path $project_name/$archive_root") if (! -e "$project_name/$archive_root"); -} -else { - - # Prior output available, set relevant variables - - $project_name = $archive; - my @contents = glob("$project_name/*"); - - # Determine the archive name by looking for a symlink - my $found_name = 0; - foreach my $file (@contents) { - if (-l $file) { - $file =~ s/\Q$project_name\E\///; - #$archive = $file; - $archive = "$project_name/$file"; - $found_name = 1; - } - } - die "Could not locate archive in '$project_name'.\n" if (!$found_name); - - # Extract name information from input file - ($archive_root = $archive) =~ s/.*\/(.*)/$1/; - ($archive_root_no_ext = $archive) =~ s/(.*\/)?(.*)(\.tar\.gz)|(\.tgz)/$2/; -} - -# The name of the output archive -my $mb_archive = "$archive_root_no_ext.mb.tar"; - -chdir($project_name); - -# Change how Ctrl+C is interpreted to allow for clean up -$SIG{'INT'} = 'INT_handler'; - -# Define and initialize directories -my $gene_dir = "genes/"; -mkdir($gene_dir) or die "Could not create '$gene_dir': $!.\n" if (!-e $gene_dir); - -# Check if completed genes from a previous run exist -my %complete_genes; -if (-e $mb_archive) { - print "\nArchive containing completed MrBayes runs found for this dataset found in '$mb_archive'.\n"; - print "Completed runs contained in this archive will be removed from the job queue.\n"; - - # Add gene names in tarball to list of completed genes - chomp(my @complete_genes = `tar tf '$mb_archive'`); - foreach my $gene (@complete_genes) { - $gene =~ s/\.tar\.gz//; - $complete_genes{$gene}++; - } -} - -# Unarchive input genes -chomp(my @genes = `tar xvf '$init_dir/$archive' -C $gene_dir 2>&1`); -@genes = map { s/x //; $_ } @genes if ($os_name eq "darwin"); - -chdir($gene_dir); - -# Remove completed genes -if (%complete_genes) { - foreach my $index (reverse(0 .. $#genes)) { - if (exists($complete_genes{$genes[$index]})) { - unlink($genes[$index]); - splice(@genes, $index, 1); - } - } -} - -die "\nAll jobs have already completed.\n\n" if (!@genes); - -# Append given MrBayes block to the end of each gene -print "\nAppending MrBayes block to each gene... "; -foreach my $gene (@genes) { - open(my $gene_file, ">>", $gene) or die "Could not open '$gene': $!.\n"; - print {$gene_file} "\n", @mb_block; - close($gene_file); -} -print "done.\n\n"; - -# Returns the external IP address of this computer -chomp(my $server_ip = `dig +short myip.opendns.com \@resolver1.opendns.com 2>&1`); -if ($server_ip !~ /(?:[0-9]{1,3}\.){3}[0-9]{1,3}/) { - print "Could not determine external IP address, only local clients will be created.\n"; - $server_ip = "127.0.0.1"; -} - -# Initialize a server -my $sock = IO::Socket::INET->new( - LocalPort => $port, - Blocking => 0, - Reuse => 1, - Listen => SOMAXCONN, - Proto => 'tcp') -or die "Could not create server socket: $!.\n"; -$sock->autoflush(1); - -print "Job server successfully created.\n"; - -# Should probably do this earlier -# Determine server hostname and add to machines if none were specified by the user -chomp(my $server_hostname = `hostname`); -if (scalar(@machines) == 0) { - push(@machines, $server_hostname); - $machines{$server_hostname} = "127.0.0.1"; -} -elsif (scalar(@machines) == 1) { - # Check if the user input only the local machine in the config - if ($machines{$machines[0]} eq $server_ip) { - $machines{$machines[0]} = "127.0.0.1"; - } -} - -my @pids; -foreach my $machine (@machines) { - - # Fork and create a client on the given machine - my $pid = fork(); - if ($pid == 0) { - close(STDIN); - close(STDOUT); - close(STDERR); - - (my $script_name = $script_path) =~ s/.*\///; - - # Move required datafiles to machines, initialize clients - if ($machines{$machine} ne "127.0.0.1" && $machines{$machine} ne $server_ip) { - # Send this script to the machine - system("scp", "-q", $script_path, $machine.":/tmp"); - - # Send MrBayes executable to the machine - system("scp", "-q", $mb, $machine.":/tmp"); - - # Execute this perl script on the given machine - # -tt forces pseudo-terminal allocation and lets us stop remote processes - exec("ssh", "-tt", "$machine", "perl", "/tmp/$script_name", "--server-ip=$server_ip:$port"); - } - else { - # Send this script to the machine - system("cp", $script_path, "/tmp"); - - # Send MrBayes executable to the machine - system("cp", $mb, "/tmp"); - - # Execute this perl script on the given machine - exec("perl", "/tmp/$script_name", "--server-ip=127.0.0.1:$port"); - } - - exit(0); - } - else { - push(@pids, $pid); - } -} - -#chdir($gene_dir); - -my $select = IO::Select->new($sock); - -# Don't create zombies -$SIG{CHLD} = 'IGNORE'; - -# Stores which job is next in queue -my $job_number = 0; - -# Number of open connections to a client -my $total_connections; - -# Number of complete jobs (necessary?) -my $complete_count = 0; - -# Number of connections server has closed -my $closed_connections = 0; - -# Minimum number of connections server should expect -my $starting_connections = scalar(@machines); - -my $time = time(); -my $num_digits = get_num_digits({'NUMBER' => scalar(@genes)}); - -# Begin the server's job distribution -while ((!defined($total_connections) || $closed_connections != $total_connections) || $total_connections < $starting_connections) { - # Contains handles to clients which have sent information to the server - my @clients = $select->can_read(0); - - # Free up CPU by sleeping for 10 ms - usleep(10000); - - # Handle each ready client individually - CLIENT: foreach my $client (@clients) { - - # Client requesting new connection - if ($client == $sock) { - $total_connections++; - $select->add($sock->accept()); - } - else { - - # Get client's message - my $response = <$client>; - next if (not defined($response)); # a response should never actually be undefined - - # Client wants to send us a file - if ($response =~ /SEND_FILE: (.*)/) { - my $file_name = $1; - receive_file({'FILE_PATH' => $file_name, 'FILE_HANDLE' => $client}); - } - - # Client has finished a job - if ($response =~ /DONE (.*) \|\|/) { - $complete_count++; - printf(" Analyses complete: %".$num_digits."d/%d.\r", $complete_count, scalar(@genes)); - - # Perform appending of new gene to tarball in a fork as this can take some time - my $pid; - until (defined($pid)) { $pid = fork(); usleep(30000); } - - if ($pid == 0) { - - # Check if this is the first to complete, if so we must create the directory - my $completed_gene = $1; - if (!-e "../$mb_archive") { - system("touch", "$mb_archive"); - system("tar", "cf", "../$mb_archive", $completed_gene); - unlink($completed_gene); - } - else { - - # Obtain a file lock on archive so another process doesn't simultaneously try to add to it - open(my $mb_archive_file, "<", "../$mb_archive"); - flock($mb_archive_file, LOCK_EX) || die "Could not lock '$mb_archive_file': $!.\n"; - - # Add completed gene - system("tar", "rf", "../$mb_archive", $completed_gene); - unlink($completed_gene); - - # Release lock - flock($mb_archive_file, LOCK_UN) || die "Could not unlock '$mb_archive_file': $!.\n"; - close($mb_archive_file); - - } - exit(0); - } - else { - push(@pids, $pid); - } - } - - # Client wants a new job - if ($response =~ /NEW: (.*)/) { - my $client_ip = $1; - - # Check if jobs remain in the queue - if ($job_number < scalar(@genes)) { - printf("\n Analyses complete: %".$num_digits."d/%d.\r", 0, scalar(@genes)) if ($job_number == 0); - - my $gene = $genes[$job_number]; - - # Check whether the client is remote or local, send it needed files if remote - if ($client_ip ne $server_ip) { - - # Fork to perform the file transfer and prevent stalling the server - my $pid; - until (defined($pid)) { $pid = fork(); usleep(30000); } - - #my $pid = fork(); - if ($pid == 0) { - send_file({'FILE_PATH' => $gene, 'FILE_HANDLE' => $client}); - unlink($gene); - - print {$client} "NEW: $gene\n"; - exit(0); - } - else { - push(@pids, $pid); - } - } - else { - print {$client} "CHDIR: ".abs_path("./")."\n"; - print {$client} "NEW: $gene\n"; - } - $job_number++; - } - else { - # Client has asked for a job, but there are none remaining - print {$client} "HANGUP\n"; - $select->remove($client); - $client->close(); - $closed_connections++; - next CLIENT; - } - } - } - } -} - -# Don't think this is needed -foreach my $pid (@pids) { - waitpid($pid, 0); -} - -print "\n All connections closed.\n"; -print "Total execution time: ", sec2human(time() - $time), ".\n\n"; - -# Go back to project directory, delete empty gene dir -chdir(".."); -&INT_handler; - -sub client { - my ($opt_name, $address) = @_; - - my ($server_ip, $port) = split(":", $address); - - chdir("/tmp"); - my $mb = "/tmp/mb"; - - #my $pgrp = getpgrp(); - my $pgrp = $$; - setpgrp(); - - # Determine this host's IP - chomp(my $ip = `dig +short myip.opendns.com \@resolver1.opendns.com`); - - # Set IP to localhost if we don't have internet - if ($ip !~ /(?:[0-9]{1,3}\.){3}[0-9]{1,3}/) { - $ip = "127.0.0.1"; - } - - # Spawn more clients - my @pids; - # my $total_forks = get_free_cpus(); - # A slightly modification in order to limit forks to 10 - my $total_forks = 12; - if ($total_forks > 1) { - foreach my $fork (1 .. $total_forks - 1) { - - my $pid = fork(); - if ($pid == 0) { - last; - } - else { - push(@pids, $pid); - } - } - } - - # The name of the gene we are working on - my $gene; - - # Stores filenames of unneeded files - my @unlink; - - # Change signal handling so killing the server kills these processes and cleans up - $SIG{CHLD} = 'IGNORE'; - $SIG{HUP} = sub { unlink($0, $mb); kill -15, $$; }; - $SIG{TERM} = sub { unlink(glob($gene."*")) if defined($gene); exit(0)}; - - # Connect to the server - my $sock = new IO::Socket::INET( - PeerAddr => $server_ip.":".$port, - Proto => 'tcp') - or exit(0); - $sock->autoflush(1); - - print {$sock} "NEW: $ip\n"; - while (chomp(my $response = <$sock>)) { - - if ($response =~ /SEND_FILE: (.*)/) { - my $file_name = $1; - receive_file({'FILE_PATH' => $file_name, 'FILE_HANDLE' => $sock}); - } - elsif ($response =~ /CHDIR: (.*)/) { - chdir($1); - } - elsif ($response =~ /NEW: (.*)/) { - $gene = $1; - - # Redirect STDOUT to a log file - open(my $std_out, ">&", *STDOUT); - open(STDOUT, ">", $gene.".log"); - - system($mb, $gene); - - # Put STDOUT back to normal - open(STDOUT, ">&", $std_out); - close($std_out); - - unlink($gene); - - # Zip and tarball the results - my @results = glob($gene."*"); - my $gene_archive_name = "$gene.tar.gz"; - @results = grep {!/\Q$gene_archive_name\E/} @results; - system("tar", "czf", $gene_archive_name, @results); - unlink(@results); - - # Send the results back to the server if this is a remote client - if ($server_ip ne "127.0.0.1" && $server_ip ne $ip) { - send_file({'FILE_PATH' => $gene_archive_name, 'FILE_HANDLE' => $sock}); - unlink($gene_archive_name); - } - - # Request a new job - print {$sock} "DONE $gene_archive_name || NEW: $ip\n"; - } - elsif ($response eq "HANGUP") { - last; - } - } - - # Have initial client wait for all others to finish and clean up - if ($$ == $pgrp) { - foreach my $pid (@pids) { - waitpid($pid, 0); - } - unlink($0, $mb); - } - - exit(0); -} - -sub check_nonconvergent { - my ($opt_name, $threshold) = @_; - - # We have to do weird things here to get the input name - - my @ARGV = split(/\s+/, $invocation); - shift(@ARGV); shift(@ARGV); - - # Look for a directory in arguments provided - my $archive; - foreach my $arg (@ARGV) { - if (-d $arg) { - $archive = $arg; - } - } - - # Die if user didn't give us a directory - if (!defined($archive)) { - print "You must specify a directory previously generated by this script to check for nonconvergent genes.\n"; - exit(0); - } - - # Prior output available, set relevant variables - - $project_name = $archive; - my @contents = glob("$project_name/*"); - - # Determine the archive name by looking for a symlink - my $found_name = 0; - foreach my $file (@contents) { - if (-l $file) { - $file =~ s/\Q$project_name\E\///; - $archive = $file; - $found_name = 1; - } - } - die "Could not locate archive in '$project_name'.\n" if (!$found_name); - - chdir($project_name); - - # Extract name information from input file - (my $archive_root = $archive) =~ s/.*\/(.*)/$1/; - (my $archive_root_no_ext = $archive) =~ s/(.*\/)?(.*)(\.tar\.gz)|(\.tgz)/$2/; - - # Should have some completed genes in it - my $incomplete_archive = $archive_root_no_ext.".mb.tar"; - - # Check that the incomplete archive exists - if (!-e $incomplete_archive) { - print "Could not locate an archive containing completed MrBayes runs.\n"; - exit(0); - } - - print "\nScript was called as follows:\n$invocation\n\n"; - - # Create a temporary directory for our operations - my $check_dir = "tmp/"; - mkdir($check_dir) if (!-e $check_dir); - - $SIG{INT} = sub { remove_tree($check_dir); exit(0) }; - - # Open tarball in genes directory - chomp(my @genes = `tar xvf '$incomplete_archive' -C $check_dir 2>&1`); - @genes = map { s/x //; $_ } @genes if ($os_name eq "darwin"); - @genes = sort { (local $a = $a) =~ s/.*-(\d+)-\d+\..*/$1/; - (local $b = $b) =~ s/.*-(\d+)-\d+\..*/$1/; - $a <=> $b } @genes; - my $longest_name_length = length($genes[$#genes]); - - print "MrBayes results available for ", scalar(@genes), " total genes:\n"; - - chdir($check_dir); - - $SIG{INT} = sub { chdir(".."); remove_tree($check_dir); exit(0) }; - - # Parse log of each gene to determine final standard deviation of split frequencies - - my $count = 0; - foreach my $gene (@genes) { - - chomp(my @contents = `tar xvf '$gene' 2>&1`); - @contents = map { s/x //; $_ } @contents if ($os_name eq "darwin"); - - (my $log_file_path = $gene) =~ s/\.tar\.gz$/.log/; - - # Check log file exists - if (!-e $log_file_path) { - print "Could not locate log file for '$gene'.\n"; - exit(0); - } - - open(my $log_file, "<", $log_file_path); - chomp(my @data = <$log_file>); - close($log_file); - - my @splits = grep { /Average standard deviation of split frequencies:/ } @data; - my $final_split = pop(@splits); - - $final_split =~ s/.*frequencies: (.*)/$1/; - - #print " $gene: $final_split\n"; - printf(" %-${longest_name_length}s: %s\n", $gene, $final_split); - - if (!defined($final_split) || $final_split > $threshold) { - $count++; - } - unlink(@contents); - } - printf("%d gene(s) failed to meet the threshold of %s (%.2f%%).\n", $count, $threshold, ($count / scalar(@genes) * 100)); - - # Clean up and exit - kill(2, $$); -} - -sub remove_nonconvergent { - my ($opt_name, $threshold) = @_; - - # We have to do weird things here to get the input name - - my @ARGV = split(/\s+/, $invocation); - shift(@ARGV); shift(@ARGV); - - # Look for a directory in arguments provided - my $archive; - foreach my $arg (@ARGV) { - if (-d $arg) { - $archive = $arg; - } - } - - # Die if user didn't give us a directory - if (!defined($archive)) { - print "You must specify a directory previously generated by this script to check for nonconvergent genes.\n"; - exit(0); - } - - my $initial_archive = $archive; - - # Prior output available, set relevant variables - - $project_name = $archive; - my @contents = glob("$project_name/*"); - - # Determine the archive name by looking for a symlink - my $found_name = 0; - foreach my $file (@contents) { - if (-l $file) { - $file =~ s/\Q$project_name\E\///; - $archive = $file; - $found_name = 1; - } - } - die "Could not locate archive in '$project_name'.\n" if (!$found_name); - - chdir($project_name); - - # Extract name information from input file - (my $archive_root = $archive) =~ s/.*\/(.*)/$1/; - (my $archive_root_no_ext = $archive) =~ s/(.*\/)?(.*)(\.tar\.gz)|(\.tgz)/$2/; - - # Should have some completed genes in it - my $incomplete_archive = $archive_root_no_ext.".mb.tar"; - - # Check that the incomplete archive exists - if (!-e $incomplete_archive) { - print "Could not locate an archive containing completed MrBayes runs.\n"; - exit(0); - } - - print "\nScript was called as follows:\n$invocation\n\n"; - - # Create a temporary directory for our operations - my $check_dir = "tmp/"; - mkdir($check_dir) if (!-e $check_dir); - - $SIG{INT} = sub { remove_tree($check_dir); exit(0) }; - - # Open tarball in genes directory - chomp(my @genes = `tar xvf '$incomplete_archive' -C $check_dir 2>&1`); - @genes = map { s/x //; $_ } @genes if ($os_name eq "darwin"); - @genes = sort { (local $a = $a) =~ s/.*-(\d+)-\d+\..*/$1/; - (local $b = $b) =~ s/.*-(\d+)-\d+\..*/$1/; - $a <=> $b } @genes; - my $longest_name_length = length($genes[$#genes]); - - print "MrBayes results available for ", scalar(@genes), " total genes:\n"; - - chdir($check_dir); - - $SIG{INT} = sub { chdir(".."); remove_tree($check_dir); exit(0) }; - - # Parse log of each gene to determine final standard deviation of split frequencies - - my $count = 0; - foreach my $gene (@genes) { - - chomp(my @contents = `tar xvf '$gene' 2>&1`); - @contents = map { s/x //; $_ } @contents if ($os_name eq "darwin"); - - (my $log_file_path = $gene) =~ s/\.tar\.gz$/.log/; - - # Check log file exists - if (!-e $log_file_path) { - print "Could not locate log file for '$gene'.\n"; - exit(0); - } - - open(my $log_file, "<", $log_file_path); - chomp(my @data = <$log_file>); - close($log_file); - - my @splits = grep { /Average standard deviation of split frequencies:/ } @data; - my $final_split = pop(@splits); - - $final_split =~ s/.*frequencies: (.*)/$1/; - - #print " $gene: $final_split"; - if (!defined($final_split) || $final_split > $threshold) { - unlink($gene); - #print " -- REMOVED\n"; - printf(" %-${longest_name_length}s: %s -- REMOVED\n", $gene, $final_split); - $count++; - } - else { - printf(" %-${longest_name_length}s: %s\n", $gene, $final_split); - #print "\n"; - } - unlink(@contents); - } - printf("%d gene(s) failed to meet the threshold of %s (%.2f%%) and have been removed.\n", $count, $threshold, ($count / scalar(@genes) * 100)); - - # Determine which genes met threshold and still remain - @genes = glob($archive_root_no_ext."*.nex.tar.gz"); - @genes = sort { (local $a = $a) =~ s/.*-(\d+)-\d+\..*/$1/; - (local $b = $b) =~ s/.*-(\d+)-\d+\..*/$1/; - $a <=> $b } @genes; - - # Recreate archive with remaining genes - if (@genes) { - system("tar", "cf", $incomplete_archive, @genes); - unlink(@genes); - system("mv", $incomplete_archive, ".."); - } - else { - # Delete the working directory if no genes meet the threshold - print "No genes met the threshold, removing specified directory.\n"; - - chdir($initial_directory); - $SIG{INT} = sub { remove_tree($initial_archive); exit(0) }; - } - - # Clean up and exit - kill(2, $$); -} - -sub hashsum { - my $settings = shift; - - my $file_path = $settings->{'FILE_PATH'}; - - open(my $file, "<", $file_path) or die "Couldn't open file '$file_path': $!.\n"; - my $md5 = Digest::MD5->new; - my $md5sum = $md5->addfile(*$file)->hexdigest; - close($file); - - return $md5sum; -} - -sub send_file { - my $settings = shift; - - my $file_path = $settings->{'FILE_PATH'}; - my $file_handle = $settings->{'FILE_HANDLE'}; - - my $hash = hashsum({'FILE_PATH' => $file_path}); - print {$file_handle} "SEND_FILE: $file_path\n"; - - open(my $file, "<", $file_path) or die "Couldn't open file '$file_path': $!.\n"; - while (<$file>) { - print {$file_handle} $_; - } - close($file); - - print {$file_handle} " END_FILE: $hash\n"; - - # Stall until we know status of file transfer - while (defined(my $response = <$file_handle>)) { - chomp($response); - - last if ($response eq "TRANSFER_SUCCESS"); - die "Unsuccessful file transfer, checksums did not match.\n" if ($response eq "TRANSFER_FAILURE"); - } -} - -sub receive_file { - my $settings = shift; - - my $file_path = $settings->{'FILE_PATH'}; - my $file_handle = $settings->{'FILE_HANDLE'}; - - my $check_hash; - open(my $file, ">", $file_path); - while (<$file_handle>) { - if ($_ =~ /(.*) END_FILE: (\S+)/) { - print {$file} $1; - $check_hash = $2; - last; - } - else { - print {$file} $_; - } - } - close($file); - - # Use md5 hashsum to make sure transfer worked - my $hash = hashsum({'FILE_PATH' => $file_path}); - if ($hash ne $check_hash) { - die "Unsuccessful file transfer, checksums do not match.\n'$hash' - '$check_hash'\n"; # hopefully this never pops up - print {$file_handle} "TRANSFER_FAILURE\n" - } - - else { - print {$file_handle} "TRANSFER_SUCCESS\n"; - } -} - -sub INT_handler { - - # Kill ssh process(es) spawn by this script - foreach my $pid (@pids) { - #kill(-1, $pid); - kill(15, $pid); - } - - # Move into gene directory - #chdir("$initial_directory"); - chdir("$initial_directory/$project_name"); - - # Try to delete directory five times, if it can't be deleted print an error message - # I've found this method is necessary for analyses performed on AFS drives - my $count = 0; - until (!-e $gene_dir || $count == 5) { - $count++; - - remove_tree($gene_dir, {error => \my $err}); - sleep(1); - } - #logger("Could not clean all files in './$gene_dir/'.") if ($count == 5); - print "Could not clean all files in './$gene_dir/'.\n" if ($count == 5); - - exit(0); -} - -sub clean_up { - my $settings = shift; - - my $remove_dirs = $settings->{'DIRS'}; - my $current_dir = getcwd(); - -# chdir($alignment_root); -# unlink(glob($gene_dir."$alignment_name*")); -# #unlink($server_check_file) if (defined($server_check_file)); -# -# if ($remove_dirs) { -# rmdir($gene_dir); -# } - chdir($current_dir); -} - -sub get_num_digits { - my $settings = shift; - - my $number = $settings->{'NUMBER'}; - - my $digits = 1; - while (floor($number / 10) != 0) { - $number = floor($number / 10); - $digits++; - } - - return $digits; -} - -sub sec2human { - my $secs = shift; - - # Constants - my $secs_in_min = 60; - my $secs_in_hour = 60 * 60; - my $secs_in_day = 24 * 60 * 60; - - $secs = int($secs); - - return "0 seconds" if (!$secs); - - # Calculate units of time - my $days = int($secs / $secs_in_day); - my $hours = ($secs / $secs_in_hour) % 24; - my $mins = ($secs / $secs_in_min) % 60; - $secs = $secs % 60; - - # Format return nicely - my $time; - if ($days) { - $time .= ($days != 1) ? "$days days, " : "$days day, "; - } - if ($hours) { - $time .= ($hours != 1) ? "$hours hours, " : "$hours hour, "; - } - if ($mins) { - $time .= ($mins != 1) ? "$mins minutes, " : "$mins minute, "; - } - if ($secs) { - $time .= ($secs != 1) ? "$secs seconds " : "$secs second "; - } - else { - # Remove comma - chop($time); - } - chop($time); - - return $time; -} - -sub get_free_cpus { - - return $max_forks if (defined($max_forks)); - - my $os_name = $^O; - - # Returns a two-member array containing CPU usage observed by top, - # top is run twice as its first output is usually inaccurate - my @percent_free_cpu; - if ($os_name eq "darwin") { - # Mac OS - chomp(@percent_free_cpu = `top -i 1 -l 2 | grep "CPU usage"`); - } - else { - # Linux - chomp(@percent_free_cpu = `top -b -n2 -d0.05 | grep "Cpu(s)"`); - } - - my $percent_free_cpu = pop(@percent_free_cpu); - - if ($os_name eq "darwin") { - # Mac OS - $percent_free_cpu =~ s/.*?(\d+\.\d+)%\s+id.*/$1/; - } - else { - # linux - $percent_free_cpu =~ s/.*?(\d+\.\d)\s*%?ni,\s*(\d+\.\d)\s*%?id.*/$1 + $2/; # also includes %nice as free - $percent_free_cpu = eval($percent_free_cpu); - } - - my $total_cpus; - if ($os_name eq "darwin") { - # Mac OS - $total_cpus = `sysctl -n hw.ncpu`; - } - else { - # linux - $total_cpus = `grep --count 'cpu' /proc/stat` - 1; - } - - my $free_cpus = ceil($total_cpus * $percent_free_cpu / 100); - - if ($free_cpus == 0 || $free_cpus !~ /^\d+$/) { - $free_cpus = 1; # assume that at least one cpu can be used - } - - return $free_cpus; -} - -sub run_cmd { - my $command = shift; - - my $return = system($command); - - if ($return) { - logger("'$command' died with error: '$return'.\n"); - #kill(2, $parent_pid); - exit(0); - } -} - -sub check_path_for_exec { - my $exec = shift; - - my $path = $ENV{PATH}.":."; # include current directory as well - my @path_dirs = split(":", $path); - - my $exec_path; - foreach my $dir (@path_dirs) { - $dir .= "/" if ($dir !~ /\/$/); - $exec_path = abs_path($dir.$exec) if (-e $dir.$exec && -x $dir.$exec && !-d $dir.$exec); - } - - die "Could not find the following executable: '$exec'. This script requires this program in your path.\n" if (!defined($exec_path)); - return $exec_path; -} - -sub usage { - return "Usage: mb.pl ([PARTITION TARBALL] [-m MRBAYES BLOCK]) || ([MRBAYES TARBALL] [-c THRESHOLD] || [-r THRESHOLD])\n"; -} - -sub help { -print < -EOF -exit(0); -} diff --git a/99.scripts/workflow/orthology_inference/04.filter_ogs.sh b/99.scripts/workflow/orthology_inference/04.filter_ogs.sh new file mode 100755 index 0000000..8b77dca --- /dev/null +++ b/99.scripts/workflow/orthology_inference/04.filter_ogs.sh @@ -0,0 +1,23 @@ +#! /bin/bash +set -e +if [ "$#" -ne 4 ]; then + echo "Usage: $0 " + echo "Filter orthologous groups after TreeShrink based on minimum taxon number and minimum sequence length" + exit 1 +fi + +out_dir=$(readlink -f "$1") +treeshrink_dir=$(readlink -f "$2") +min_taxon=$3 +min_seq_length=$4 + +mkdir -p "$out_dir" +for i in "$treeshrink_dir"/*/output.fasta; do + j=$(dirname "$i") + j=$(basename "$j") + seqlen=$(seqkit fx2tab -C ATCG "$i" | awk '{print $3}' | sort -n | head -n 1) + seqnum=$(grep -c ">" "$i") + if [[ $seqnum -eq $min_taxon && $seqlen -ge $min_seq_length ]]; then + cp -l "$i" "$out_dir"/"${j}.fa" + fi +done diff --git a/99.scripts/workflow/orthology_inference/09.filter_ogs.sh b/99.scripts/workflow/orthology_inference/09.filter_ogs.sh deleted file mode 100755 index ac14150..0000000 --- a/99.scripts/workflow/orthology_inference/09.filter_ogs.sh +++ /dev/null @@ -1,12 +0,0 @@ -#! /usr/bin/env bash -total_taxon=11 -min_seq_length=300 -mkdir -p final_ogs -for i in treeshrink/* ; do - j=$(basename "$i") - seqlen=$(seqkit fx2tab -C ATCG "$i"/output.fasta | awk '{print $3}' | sort -n | head -n 1) - seqnum=$(grep -c ">" "$i"/output.fasta) - if [[ $seqnum -eq $total_taxon && $seqlen -ge $min_seq_length ]]; then - cp -l "$i"/output.fasta final_ogs/"${j}.fa" - fi -done diff --git a/99.scripts/workflow/phylogeny_reconstruction/01.modeltest.sh b/99.scripts/workflow/phylogeny_reconstruction/01.modeltest.sh deleted file mode 100755 index 3ef0126..0000000 --- a/99.scripts/workflow/phylogeny_reconstruction/01.modeltest.sh +++ /dev/null @@ -1,7 +0,0 @@ -#! /usr/bin/env bash -mkdir -p modeltests -for i in ../gene_alignment/*.fa ; do - j=$(basename "$i") - echo "modeltest-ng -p 2 -r 12345 --force -i $i -d nt -t ml -o modeltests/${j/.fa/}.modeltest" >> modeltest.cmds -done -xargs -t -P 4 -I cmd -a modeltest.cmds bash -c "cmd" diff --git a/99.scripts/workflow/phylogeny_reconstruction/01.run_mrbayes.sh b/99.scripts/workflow/phylogeny_reconstruction/01.run_mrbayes.sh new file mode 100755 index 0000000..d627a57 --- /dev/null +++ b/99.scripts/workflow/phylogeny_reconstruction/01.run_mrbayes.sh @@ -0,0 +1,21 @@ +#! /bin/bash +set -e +SCRIPTS=${SCRIPTS:-"$PROJECTHOME/99.scripts"} + +if [ "$#" -ne 3 ]; then + echo "Usage: $0 " + echo "Run MrBayes for each fasta file in the input directory" + exit 1 +fi + +input_dir=$(readlink -f "$1") +ext=$2 +output_dir=$(readlink -f "$3") +mkdir -p "${output_dir}" +echo -n >mrbayes.cmds +for f in "${input_dir}"/*."${ext}"; do + j=$(basename "$f" ."${ext}") + echo "bash $SCRIPTS/miscs/mrbayes.sh $f ${output_dir}/${j}/${j}.nex" >>mrbayes.cmds +done +xargs -t -P 12 -I cmd -a mrbayes.cmds bash -c "cmd" +echo "All MrBayes analyses are done!" diff --git a/99.scripts/workflow/phylogeny_reconstruction/02.mbsum.sh b/99.scripts/workflow/phylogeny_reconstruction/02.mbsum.sh new file mode 100755 index 0000000..7dbe6ac --- /dev/null +++ b/99.scripts/workflow/phylogeny_reconstruction/02.mbsum.sh @@ -0,0 +1,31 @@ +#!/bin/bash +THREADS=${THREADS:-12} +MIN_DSF=${MIN_DSF:-0.01} + +if [ "$#" -ne 3 ]; then + echo "Usage: $0 " + echo "Summarize MrBayes output using mbsum, skipping analyses with high DSF" + exit 1 +fi + +mb_dir=$(readlink -f "$1") +mbsum_out_dir=$2 +num_skip=$3 + +mkdir -p "$mbsum_out_dir" +echo -n "" >mbsum.skip.log +echo -n "" >mbsum.cmds +for i in "$mb_dir"/*/mrbayes.log; do + og_dir=$(dirname "$i") + base=$(basename "$og_dir") + ## skip Average standard deviation of split frequencies > 0.01 + dsf=$(awk '/Average standard deviation of split frequencies:/ {out=$7} END{print out+0}' "$i" 2>/dev/null) + if awk -v d="$dsf" -v min_dsf="$MIN_DSF" 'BEGIN{if (d >= min_dsf) exit 0; exit 1}'; then + echo "Skipping ${base} due to high DSF: ${dsf}" >>mbsum.skip.log + continue + else + echo "mbsum ${og_dir}/*.t -n $num_skip -o $mbsum_out_dir/${base}.in >> $og_dir/mbsum.log 2>&1" >>mbsum.cmds + fi +done +xargs -t -P "$THREADS" -I cmd -a mbsum.cmds bash -c "cmd" +echo "Mbsum all done!" diff --git a/99.scripts/workflow/phylogeny_reconstruction/02.raxml_per_gene.sh b/99.scripts/workflow/phylogeny_reconstruction/02.raxml_per_gene.sh deleted file mode 100755 index 9736f0f..0000000 --- a/99.scripts/workflow/phylogeny_reconstruction/02.raxml_per_gene.sh +++ /dev/null @@ -1,9 +0,0 @@ -#! /usr/bin/env bash -mkdir -p raxml_ng -echo -n > raxml_ng.cmds -for i in modeltests/*.modeltest.out ; do - j=$(basename "$i") - cmd=$(grep "raxml-ng" "$i" | tail -n 1 | sed 's/> //') - echo "$cmd --all --bs-trees 1000 --outgroup Zju --redo --threads 4 --seed 12345 --prefix raxml_ng/${j/.modeltest.out/} > /dev/null" >> raxml_ng.cmds -done -xargs -t -P 3 -I cmd -a raxml_ng.cmds bash -c "cmd" diff --git a/99.scripts/workflow/phylogeny_reconstruction/03.run_raxml.sh b/99.scripts/workflow/phylogeny_reconstruction/03.run_raxml.sh new file mode 100755 index 0000000..1f32f66 --- /dev/null +++ b/99.scripts/workflow/phylogeny_reconstruction/03.run_raxml.sh @@ -0,0 +1,23 @@ +#! /bin/bash +set -e +SCRIPTS=${SCRIPTS:-"$PROJECTHOME/99.scripts"} +THREADS=${THREADS:-4} + +if [ "$#" -ne 3 ]; then + echo "Usage: $0 " + echo "Run raxml-ng on filtered orthogroup alignments" + exit 1 +fi + +in_dir=$(readlink -f "$1") +out_dir=$2 +ext=$3 +mkdir -p "$out_dir" +echo -n >raxml.cmds +for i in "$in_dir"/*."$ext"; do + j=$(basename "$i" ."$ext") + out_prefix="$out_dir/${j}/${j}" + echo "$SCRIPTS/miscs/raxml.sh $i $out_prefix 4 Zju" >>raxml.cmds +done +xargs -t -P "$THREADS" -I cmd -a raxml.cmds bash -c "cmd" +echo "Raxml-ng all completed." diff --git a/99.scripts/workflow/phylogeny_reconstruction/07.mbsum.sh b/99.scripts/workflow/phylogeny_reconstruction/07.mbsum.sh deleted file mode 100755 index 7d765fb..0000000 --- a/99.scripts/workflow/phylogeny_reconstruction/07.mbsum.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -mkdir -p ../mbsum_out -echo -n "" > ../mbsum.log -for i in *.nex.tar.gz; do - base=$(basename "$i" .nex.tar.gz) - echo "Processing ${base}" >> ../mbsum.log - mkdir -p "${base}" - tar -xzf "$i" -C "${base}" - ## skip Average standard deviation of split frequencies > 0.01 - dsf=$(awk '/Average standard deviation of split frequencies:/ {out=$7} END{print out+0}' "${base}"/*.nex.log 2>/dev/null) - if awk -v d="$dsf" 'BEGIN{if (d >= 0.01) exit 0; exit 1}'; then - echo "Skipping ${base} due to high DSF: ${dsf}" >> ../mbsum.log - continue - else - mbsum "${base}"/*.t -n 1000 -o ../mbsum_out/"${base}".in >> ../mbsum.log 2>&1 - fi - rm -rf "${base}" - echo "Completed ${base}" >> ../mbsum.log -done -echo "All done!" diff --git a/pixi.lock b/pixi.lock index 1aa5e90..5e58bac 100644 --- a/pixi.lock +++ b/pixi.lock @@ -1,5 +1,78 @@ version: 6 environments: + beast: + channels: + - url: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ + - url: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/ + - url: https://conda.anaconda.org/conda-forge/ + - url: https://conda.anaconda.org/bioconda/ + packages: + linux-64: + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/alsa-lib-1.2.15.1-hb03c661_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/linux-64/beagle-lib-4.0.1-h9948957_3.tar.bz2 + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/noarch/beast-10.5.0-hdfd78af_0.tar.bz2 + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/icu-75.1-he02047a_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/openjdk-25.0.1-h5755bd7_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxt-1.3.1-hb9d3cd8_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda default: channels: - url: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ @@ -22,8 +95,7 @@ environments: - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/linux-64/augustus-3.5.0-pl5321h57ba348_8.tar.bz2 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/linux-64/bamtools-2.5.3-he132191_0.tar.bz2 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/linux-64/bbmap-39.37-he5f24ec_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/linux-64/beagle-lib-4.0.1-h9948957_3.tar.bz2 - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/noarch/beast-10.5.0-hdfd78af_0.tar.bz2 + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/linux-64/beagle-lib-3.1.2-h503566f_5.tar.bz2 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/binutils_impl_linux-64-2.45-h9d8b0ac_0.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/noarch/bioconductor-annotate-1.84.0-r44hdfd78af_0.tar.bz2 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/noarch/bioconductor-annotationdbi-1.68.0-r44hdfd78af_0.tar.bz2 @@ -239,6 +311,7 @@ environments: - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libldl-3.3.2-hf02c80a_7100101.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libllvm20-20.1.8-hecd9e04_0.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libllvm21-21.1.0-hecd9e04_0.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libltdl-2.4.3a-h5888daf_0.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/liblzma-devel-5.8.1-hb9d3cd8_2.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libmamba-2.3.2-hae34dd5_2.conda @@ -272,6 +345,7 @@ environments: - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libsuitesparseconfig-7.10.1-h901830b_7100101.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_2.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libtool-2.5.4-h5888daf_0.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libtorch-2.6.0-cpu_generic_haed06de_0.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libumfpack-6.3.5-h873dde6_7100101.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libunistring-0.9.10-h7f98852_0.tar.bz2 @@ -312,6 +386,7 @@ environments: - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/mpg123-1.32.9-hc50e24c_0.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/mpi-1.0-openmpi.tar.bz2 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda + - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/linux-64/mrbayes-3.2.7-hd0d793b_7.tar.bz2 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/linux-64/muscle-3.8.1551-h9948957_9.tar.bz2 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/mysql-connector-c-6.1.11-h659d440_1008.conda @@ -337,7 +412,6 @@ environments: - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/ossuuid-1.6.2-h5888daf_1001.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/p7zip-16.02-h9c3ff4c_1001.tar.bz2 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/noarch/pal2nal-14.1-pl5321hdfd78af_3.tar.bz2 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/linux-64/paml-4.10.9-h7b50bb2_1.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_1.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/pandoc-3.8.2.1-ha770c72_0.conda @@ -370,7 +444,6 @@ environments: - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/perl-file-path-2.18-pl5321hd8ed1ab_0.tar.bz2 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/perl-file-temp-0.2304-pl5321hd8ed1ab_0.tar.bz2 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/perl-file-which-1.24-pl5321hd8ed1ab_0.tar.bz2 - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/noarch/perl-getopt-long-2.58-pl5321hdfd78af_0.tar.bz2 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/perl-importer-0.026-pl5321hd8ed1ab_0.tar.bz2 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/perl-inc-latest-0.500-pl5321ha770c72_0.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/linux-64/perl-io-compress-2.213-pl5321h503566f_0.conda @@ -728,88 +801,6 @@ environments: - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/zlib-ng-2.2.5-hde8ca8f_0.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda - mrbayes: - channels: - - url: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ - - url: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/ - - url: https://conda.anaconda.org/conda-forge/ - - url: https://conda.anaconda.org/bioconda/ - packages: - linux-64: - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/linux-64/beagle-lib-3.1.2-h503566f_5.tar.bz2 - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/icu-75.1-he02047a_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_7.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_7.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libgfortran5-15.2.0-hcd61629_7.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libglib-2.86.1-h32235b2_2.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libltdl-2.4.3a-h5888daf_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libpng-1.6.50-h421ea60_1.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libtool-2.5.4-h5888daf_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/mpi-1.0-openmpi.tar.bz2 - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/linux-64/mrbayes-3.2.7-hd0d793b_7.tar.bz2 - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/openjdk-25.0.1-h5755bd7_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/openmpi-4.1.6-hc5af2df_101.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/pcre2-10.46-h1321c63_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxt-1.3.1-hb9d3cd8_0.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda - - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda packages: - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726 @@ -846,6 +837,16 @@ packages: license_family: GPL size: 566531 timestamp: 1744668655747 +- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/alsa-lib-1.2.15.1-hb03c661_0.conda + sha256: 224f1a55a9ba7e877bce980f14fc3e3c0f0fb6d3cbf3c5f1a8f5dd8391ce8bba + md5: bba37fb066adb90e1d876dff0fd5d09d + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: LGPL-2.1-or-later + license_family: GPL + size: 585491 + timestamp: 1766155792553 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda sha256: b08ef033817b5f9f76ce62dfcac7694e7b6b4006420372de22494503decac855 md5: 346722a0be40f6edc53f12640d301338 @@ -3515,6 +3516,18 @@ packages: license_family: MIT size: 74811 timestamp: 1752719572741 +- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda + sha256: 1e1b08f6211629cbc2efe7a5bca5953f8f6b3cae0eeb04ca4dacee1bd4e2db2f + md5: 8b09ae86839581147ef2e5c5e229d164 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - expat 2.7.3.* + license: MIT + license_family: MIT + size: 76643 + timestamp: 1763549731408 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda sha256: 25cbdfa65580cfab1b8d15ee90b4c9f1e0d72128f1661449c9a999d341377d54 md5: 35f29eec58405aaf55e01cb470d8c26a @@ -3572,6 +3585,19 @@ packages: license_family: GPL size: 822552 timestamp: 1759968052178 +- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda + sha256: 6eed58051c2e12b804d53ceff5994a350c61baf117ec83f5f10c953a3f311451 + md5: 6d0363467e6ed84f11435eb309f2ff06 + depends: + - __glibc >=2.17,<3.0.a0 + - _openmp_mutex >=4.5 + constrains: + - libgcc-ng ==15.2.0=*_16 + - libgomp 15.2.0 he0feb66_16 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 1042798 + timestamp: 1765256792743 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/libgcc-devel_linux-64-15.2.0-h73f6952_107.conda sha256: 67323768cddb87e744d0e593f92445cd10005e04259acd3e948c7ba3bcb03aed md5: 85fce551e54a1e81b69f9ffb3ade6aee @@ -3581,6 +3607,15 @@ packages: license_family: GPL size: 2728965 timestamp: 1759967882886 +- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda + sha256: 5f07f9317f596a201cc6e095e5fc92621afca64829785e483738d935f8cab361 + md5: 5a68259fac2da8f2ee6f7bfe49c9eb8b + depends: + - libgcc 15.2.0 he0feb66_16 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 27256 + timestamp: 1765256804124 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda sha256: 2045066dd8e6e58aaf5ae2b722fb6dfdbb57c862b5f34ac7bfb58c40ef39b6ad md5: 280ea6eee9e2ddefde25ff799c4f0363 @@ -3686,6 +3721,21 @@ packages: license: LGPL-2.1-or-later size: 3933707 timestamp: 1762787455198 +- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda + sha256: 82d6c2ee9f548c84220fb30fb1b231c64a53561d6e485447394f0a0eeeffe0e6 + md5: 034bea55a4feef51c98e8449938e9cee + depends: + - __glibc >=2.17,<3.0.a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - pcre2 >=10.47,<10.48.0a0 + constrains: + - glib 2.86.3 *_0 + license: LGPL-2.1-or-later + size: 3946542 + timestamp: 1765221858705 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda sha256: 1175f8a7a0c68b7f81962699751bb6574e6f07db4c9f72825f978e3016f46850 md5: 434ca7e50e40f4918ab701e3facd59a0 @@ -3713,6 +3763,15 @@ packages: license_family: GPL size: 447919 timestamp: 1759967942498 +- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda + sha256: 5b3e5e4e9270ecfcd48f47e3a68f037f5ab0f529ccb223e8e5d5ac75a58fc687 + md5: 26c46f90d0e727e95c6c9498a33a09f3 + depends: + - __glibc >=2.17,<3.0.a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 603284 + timestamp: 1765256703881 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libheif-1.19.7-gpl_hc18d805_100.conda sha256: ec9797d57088aeed7ca4905777d4f3e70a4dbe90853590eef7006b0ab337af3f md5: 1db2693fa6a50bef58da2df97c5204cb @@ -4092,6 +4151,16 @@ packages: license: zlib-acknowledgement size: 317390 timestamp: 1753879899951 +- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda + sha256: 8acdeb9a7e3d2630176ba8e947caf6bf4985a5148dec69b801e5eb797856688b + md5: 00d4e66b1f746cb14944cad23fffb405 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libzlib >=1.3.1,<2.0a0 + license: zlib-acknowledgement + size: 317748 + timestamp: 1764981060755 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libpq-17.6-h3675c94_2.conda sha256: 8a078b33f65c5521ae1ed9545ea21efdc46630ff618cdd01aa6a3e698149b27d md5: e2c2f4c4c20a449b3b4a218797bd7c03 @@ -4236,6 +4305,18 @@ packages: license_family: GPL size: 3898269 timestamp: 1759968103436 +- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda + sha256: 813427918316a00c904723f1dfc3da1bbc1974c5cfe1ed1e704c6f4e0798cbc6 + md5: 68f68355000ec3f1d6f26ea13e8f525f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc 15.2.0 he0feb66_16 + constrains: + - libstdcxx-ng ==15.2.0=*_16 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 5856456 + timestamp: 1765256838573 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/libstdcxx-devel_linux-64-15.2.0-h73f6952_107.conda sha256: ae5f609b3df4f4c3de81379958898cae2d9fc5d633518747c01d148605525146 md5: a888a479d58f814ee9355524cc94edf3 @@ -4254,6 +4335,15 @@ packages: license_family: GPL size: 29343 timestamp: 1759968157195 +- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda + sha256: 81f2f246c7533b41c5e0c274172d607829019621c4a0823b5c0b4a8c7028ee84 + md5: 1b3152694d236cf233b76b8c56bf0eae + depends: + - libstdcxx 15.2.0 h934c35e_16 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 27300 + timestamp: 1765256885128 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libsuitesparseconfig-7.10.1-h901830b_7100101.conda sha256: d8f32a0b0ee17fbace7af4bd34ad554cc855b9c18e0aeccf8395e1478c161f37 md5: 57ae1dd979da7aa88a9b38bfa2e1d6b2 @@ -4374,6 +4464,16 @@ packages: license_family: MIT size: 85741 timestamp: 1757742873826 +- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda + sha256: 030447cf827c471abd37092ab9714fde82b8222106f22fde94bc7a64e2704c40 + md5: 41f5c09a211985c3ce642d60721e7c3e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: BSD-3-Clause + license_family: BSD + size: 40235 + timestamp: 1764790744114 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda sha256: e5ec6d2ad7eef538ddcb9ea62ad4346fde70a4736342c4ad87bd713641eb9808 md5: 80c07c68d2f6870250959dcc95b209d1 @@ -5116,16 +5216,6 @@ packages: license_family: APACHE size: 62477 timestamp: 1745345660407 -- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/noarch/pal2nal-14.1-pl5321hdfd78af_3.tar.bz2 - sha256: aff933ffefe2ecbc31b6e38bbbb2a19b5b34c2942b3d2078d7f5848432d494f6 - md5: 2afdf27b9f28038bfb670e2059deca04 - depends: - - perl >=5.32.1,<6.0a0 *_perl5 - - perl-getopt-long - license: GPLv2.0 - license_family: GPL - size: 22693 - timestamp: 1642293349880 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/linux-64/paml-4.10.9-h7b50bb2_1.conda sha256: 81c5237b07796984d7915d29a768068a1e5e6c02b4ae25f27836b0babe84e5aa md5: ef02b401c5daaf104b3d1091f8ec37f5 @@ -5260,6 +5350,18 @@ packages: license_family: BSD size: 1209177 timestamp: 1756742976157 +- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda + sha256: 5e6f7d161356fefd981948bea5139c5aa0436767751a6930cb1ca801ebb113ff + md5: 7a3bff861a6583f1889021facefc08b1 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - libgcc >=14 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 1222481 + timestamp: 1763655398280 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/perl-5.32.1-7_hd590300_perl5.conda build_number: 7 sha256: 9ec32b6936b0e37bcb0ed34f22ec3116e75b3c0964f9f50ecea5f58734ed6ce9 @@ -5515,14 +5617,6 @@ packages: license_family: OTHER size: 17329 timestamp: 1636695979827 -- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/bioconda/noarch/perl-getopt-long-2.58-pl5321hdfd78af_0.tar.bz2 - sha256: 94c17b270316f9b38cf1afa0b1724cdb6bd8349207568dccc1156b9014708c7d - md5: 10469a3defbd6dbab17d3d10dd6fd828 - depends: - - perl >=5.32.1,<6.0a0 *_perl5 - license: unknown - size: 33785 - timestamp: 1718113256479 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/noarch/perl-importer-0.026-pl5321hd8ed1ab_0.tar.bz2 sha256: f40d5302de8c81282b5216edd8c65aecc551ef725db3351c208bff9b077e66a2 md5: 66e17c342d13c39a12c1059f13f9b72c @@ -10260,6 +10354,16 @@ packages: license: BSD-3-Clause size: 466893 timestamp: 1762512695614 +- conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 + md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 + depends: + - __glibc >=2.17,<3.0.a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 601375 + timestamp: 1764777111296 - conda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda sha256: a4166e3d8ff4e35932510aaff7aa90772f84b4d07e9f6f83c614cba7ceefe0eb md5: 6432cb5d4ac0046c3ac0a8a0f95842f9 diff --git a/pixi.toml b/pixi.toml index 613d196..265221e 100644 --- a/pixi.toml +++ b/pixi.toml @@ -15,8 +15,6 @@ index-url = "https://mirrors.bfsu.edu.cn/pypi/web/simple" [tasks] -[dependencies] - [feature.base.dependencies] sra-tools = "*" fastp = "*" @@ -31,20 +29,17 @@ pip = ">=25.2,<26" seqkit = ">=2.10.1,<3" r-rstan = ">=2.32.7,<3" biopython = ">=1.85,<2" -pal2nal = ">=14.1,<15" trimal = ">=1.5.0,<2" treeshrink = ">=1.3.9,<2" r-ape = ">=5.8_1,<6" raxml-ng = ">=1.2.2,<2" modeltest-ng = ">=0.1.7,<0.2" -beast = ">=10.5.0,<11" aster = ">=1.23,<2" julia = "1.12.*" conda = ">=25.9.1,<26" r-phangorn = ">=2.12.1,<3" r-languageserver = ">=0.3.16,<0.4" seqmagick = ">=0.8.6,<0.9" -beagle-lib = "4.*" maven = ">=3.9.11,<4" matplotlib = ">=3.10.8,<4" ete3 = ">=3.1.3,<4" @@ -54,12 +49,13 @@ macse = ">=2.7,<3" td2 = ">=1.0.6,<2" mmseqs2 = ">=18.8cc5c,<19" paml = ">=4.10.9,<5" +beagle-lib = "==3.1.2" +mrbayes = ">=3.2.7,<4" -[feature.mrbayes.dependencies] -beagle-lib = ">=3.1.2,<4" -mrbayes = ">=3.2.7" +[feature.beast.dependencies] +beagle-lib = ">=4.0.1,<5" +beast = ">=10.5.0,<11" [environments] default = ["base"] -mrbayes = ["mrbayes"] - +beast = ["beast"]