[med-svn] [Git][med-team/radiant][upstream] New upstream version 2.7.1+dfsg

Andreas Tille gitlab at salsa.debian.org
Wed Jul 17 16:13:32 BST 2019



Andreas Tille pushed to branch upstream at Debian Med / radiant


Commits:
349eb89b by Andreas Tille at 2019-07-17T15:10:22Z
New upstream version 2.7.1+dfsg
- - - - -


11 changed files:

- + KronaTools/img/loading.gif
- KronaTools/install.pl
- KronaTools/lib/KronaTools.pm
- + KronaTools/scripts/ClassifyHits.pl
- KronaTools/scripts/ImportBLAST.pl
- + KronaTools/scripts/ImportHits.pl
- KronaTools/scripts/ImportMETAREP-blast.pl → KronaTools/scripts/ImportMETAREP-BLAST.pl
- KronaTools/scripts/ImportTaxonomy.pl
- KronaTools/scripts/accession2taxid.make
- KronaTools/src/krona-2.0.js
- KronaTools/updateTaxonomy.sh


Changes:

=====================================
KronaTools/img/loading.gif
=====================================
Binary files /dev/null and b/KronaTools/img/loading.gif differ


=====================================
KronaTools/install.pl
=====================================
@@ -43,6 +43,7 @@ print "Creating links...\n";
 
 foreach my $script
 (qw(
+	ClassifyHits
 	ClassifyBLAST
 	GetContigMagnitudes
 	GetLCA
@@ -54,6 +55,7 @@ foreach my $script
 	ImportEC
 	ImportFCP
 	ImportGalaxy
+	ImportHits
 	ImportKrona
 	ImportMETAREP-BLAST
 	ImportMETAREP-EC


=====================================
KronaTools/lib/KronaTools.pm
=====================================
@@ -9,6 +9,7 @@ use strict;
 package KronaTools;
 
 use Getopt::Long;
+Getopt::Long::Configure("no_ignore_case");
 use File::Basename;
 use File::Path;
 
@@ -35,6 +36,7 @@ our @EXPORT = qw
 	addByLineage
 	addByTaxID
 	addXML
+	classify
 	classifyBlast
 	default
 	getAccFromSeqID
@@ -90,7 +92,8 @@ my %options =
 	'standalone' => 1,
 	'taxCol' => 2,
 	'taxonomy' => $taxonomyDir,
-	'threshold' => 3
+	'threshold' => 3,
+	'thresholdGeneric' => 0,
 );
 
 # Option format codes to pass to GetOptions (and to be parsed for display).
@@ -113,8 +116,10 @@ my %optionFormats =
 		'e=f',
 	'include' =>
 		'i',
-	'noRank' =>
+	'cellular' =>
 		'k',
+	'noRank' =>
+		'K',
 	'local' =>
 		'l',
 	'magCol' =>
@@ -147,6 +152,8 @@ my %optionFormats =
 		't=i',
 	'threshold' =>
 		't=f',
+	'thresholdGeneric' =>
+		't=f',
 	'taxonomy' =>
 		'tax=s',
 	'url' =>
@@ -173,6 +180,7 @@ my %optionTypes =
 my %optionDescriptions =
 (
 	'bitScore' => 'Use bit score for average scores instead of log[10] e-value.',
+	'cellular' => 'Show the "cellular organisms" taxon (collapsed by default).',
 	'combine' => 'Combine data from each file, rather than creating separate datasets within the chart.',
 	'depth' => 'Maximum depth of wedges to include in the chart.',
 	'ecCol' => 'Column of input files to use as EC number.',
@@ -186,7 +194,7 @@ my %optionDescriptions =
 	'minConfidence' => 'Minimum confidence. Each query sequence will only be added to taxa that were predicted with a confidence score of at least this value.',
 	'name' => 'Name of the highest level.',
 	'noMag' => 'Files do not have a field for quantity.',
-	'noRank' => 'Allow assignments to taxa with ranks labeled "no rank" (instead of moving up to parent).',
+	'noRank' => 'Collapse assignments to taxa with ranks labeled "no rank" by moving up to parent.',
 	'out' => 'Output file name.',
 	'phymm' => 'Input is phymm only (no confidence scores).',
 	'postUrl' => 'Url to send query IDs to (instead of listing them) for each wedge. The query IDs will be sent as a comma separated list in the POST variable "queries", with the current dataset index (from 0) in the POST variable "dataset". The url can include additional variables encoded via GET.',
@@ -198,6 +206,7 @@ my %optionDescriptions =
 	'taxCol' => 'Column of input files to use as taxonomy ID.',
 	'taxonomy' => 'Path to directory containing a taxonomy database to use.',
 	'threshold' => 'Threshold for bit score differences when determining "best" hits. Hits with scores that are within this distance of the highest score will be included when computing the lowest common ancestor (or picking randomly if -r is specified).',
+	'thresholdGeneric' => 'Threshold for score differences when determining "best" hits. Hits with scores that are within this distance of the highest score will be included when computing the lowest common ancestor (or picking randomly if -r is specified). If 0, only exact ties for the best hit are used.',
 	'url' => 'URL of Krona resources to use instead of bundling them with the chart (e.g. "http://krona.sourceforge.net"). Reduces size of charts and allows updates, though charts will not work without access to this URL.',
 	'verbose' => 'Verbose.'
 );
@@ -212,6 +221,7 @@ my %optionDescriptions =
 our %argumentNames =
 (
 	'blast' => 'blast_output',
+	'hits' => 'hits',
 	'magnitude' => 'magnitudes',
 	'metarep' => 'metarep_folder',
 	'name' => 'name',
@@ -226,6 +236,12 @@ our %argumentDescriptions =
 downloading from NCBI). If running BLAST locally, subject IDs in the local
 database must contain accession numbers, either bare or in the fourth field of
 the pipe-separated ("gi|12345|xx|ABC123.1|") format.',
+	'hits' =>
+'Tabular file whose fields are [query, subject, score]. Subject must be
+an accession or contain one in the fourth field of pipe notation (e.g.
+"gi|12345|xx|ABC123.1|". The subject and score can be omitted to
+include a query that has no hits, which will be assigned a taxonomy
+ID of -1.',
 	'magnitude' =>
 'Optional file listing query IDs with magnitudes, separated by tabs. This can
 be used to account for read length or contig depth to obtain a more accurate
@@ -245,14 +261,14 @@ default, the basename of the file will be used.',
 # Global constants #
 ####################
 
-our $version = '2.7';
+our $version = '2.7.1';
 my $javascriptVersion = '2.0';
 my $javascript = "src/krona-$javascriptVersion.js";
 my $hiddenImage = 'img/hidden.png';
 my $favicon = 'img/favicon.ico';
 my $loadingImage = 'img/loading.gif';
 my $logo = 'img/logo-med.png';
-my $taxonomyHrefBase = 'http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=info&id=';
+my $taxonomyHrefBase = 'http://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=info&id=';
 my $ecHrefBase = 'http://www.chem.qmul.ac.uk/iubmb/enzyme/EC';
 my $suppDirSuffix = '.files';
 my $suppEnableFile = 'enable.js';
@@ -260,7 +276,15 @@ my $fileTaxonomy = 'taxonomy.tab';
 my $fileTaxByAcc = 'all.accession2taxid.sorted';
 my $memberLimitDataset = 10000;
 my $memberLimitTotal = 100000;
-my $columns = `tput cols`;
+my $columns;
+if (defined($ENV{TERM}))
+{
+	$columns = `tput cols`;
+}
+else
+{
+	$columns = 80;
+}
 our $minEVal = -450;
 
 
@@ -568,11 +592,11 @@ sub addByTaxID
 	#
 	while
 	(
-		! $options{'noRank'} && $taxID > 1 && $taxRanks[$taxID] eq 'no rank' ||
-		$options{'depth'} && $taxDepths[$taxID] > $options{'depth'}
+		shouldCollapse($taxID) ||
+		$options{'depth'} && getTaxDepth($taxID) > $options{'depth'}
 	)
 	{
-		$taxID = $taxParents[$taxID];
+		$taxID = getTaxParent($taxID);
 	}
 	
 	# get parent recursively
@@ -584,7 +608,7 @@ sub addByTaxID
 	{
 		$parentID = getTaxParent($parentID);
 	}
-	while (! $options{'noRank'} && $parentID > 1 && getTaxRank($parentID) eq 'no rank');
+	while ( shouldCollapse($parentID) );
 	
 	#
 	if ( $parentID != 1 )#$taxID )
@@ -759,6 +783,133 @@ sub addXML
 	}
 }
 
+sub classify
+{
+	# taxonomically classifies generic hits based on LCA (or random selection)
+	# of 'best' hits.
+	#
+	# Options used: thresholdGeneric, include, percentIdentity, random, score
+	
+	my # parameters
+	(
+		$fileName, # file with tabular hits (query, subject, score)
+		
+		# hash refs to be populated with results (keyed by query ID)
+		#
+		$taxIDs,
+		$scores
+	) = @_;
+	
+	open HITS, "<$fileName" or ktDie("Could not open $fileName\n");
+	
+	my $lastQueryID;
+	my $topScore;
+	my $ties;
+	my $taxID;
+	my %lcaSet;
+	my $totalScore;
+	
+	while ( 1 )
+	{
+		my $line = <HITS>;
+		
+		chomp $line;
+		
+		my
+		(
+			$queryID,
+			$hitID,
+			$score
+		) = split /\t/, $line;
+		
+		if ( defined $queryID && ! defined $hitID )
+		{
+			$taxIDs->{$queryID} = -1;
+			$scores->{$queryID} = 0;
+			
+			next;
+		}
+		
+		if ( $queryID ne $lastQueryID )
+		{
+			if (  $ties )
+			{
+				# add the chosen hit from the last queryID
+				
+				if ( ! $options{'random'} )
+				{
+					$taxID = taxLowestCommonAncestor(keys %lcaSet)
+				}
+				
+				$taxIDs->{$lastQueryID} = $taxID;
+				$scores->{$lastQueryID} = $totalScore / $ties;
+			}
+			
+			$ties = 0;
+			$totalScore = 0;
+			%lcaSet = ();
+		}
+		
+		if ( ! defined $hitID )
+		{
+			last; # EOF
+		}
+		
+		my $acc = getAccFromSeqID($hitID);
+		
+		if ( ! defined $acc )
+		{
+			$lastQueryID = $queryID;
+			next;
+		}
+		
+		if # this is a 'best' hit if...
+		(
+			$queryID ne $lastQueryID || # new query ID (including null at EOF)
+			$score >= $topScore - $options{'thresholdGeneric'} # within score threshold
+		)
+		{
+			# add score for average
+			#
+			$totalScore += $score;
+			$ties++;
+			
+			if # use this hit if...
+			(
+				! $options{'random'} || # using LCA
+				$queryID ne $lastQueryID || # new query ID
+				int(rand($ties)) == 0 # randomly chosen to replace other hit
+			)
+			{
+				my $newTaxID = getTaxIDFromAcc($acc);
+				
+				if ( ! $newTaxID || ! taxIDExists($newTaxID) )
+				{
+					$newTaxID = 1;
+				}
+				
+				if ( $options{'random'} )
+				{
+					$taxID = $newTaxID;
+				}
+				else
+				{
+					$lcaSet{$newTaxID} = 1;
+				}
+			}
+		}
+		
+		if ( $queryID ne $lastQueryID )
+		{
+			$topScore = $score;
+		}
+		
+		$lastQueryID = $queryID;
+	}
+	
+	close HITS;
+}	
+
 sub classifyBlast
 {
 	# taxonomically classifies BLAST results based on LCA (or random selection)
@@ -868,7 +1019,7 @@ sub classifyBlast
 		if # this is a 'best' hit if...
 		(
 			$queryID ne $lastQueryID || # new query ID (including null at EOF)
-			$bitScore > $topScore - $options{'threshold'} || # within score threshold
+			$bitScore >= $topScore - $options{'threshold'} || # within score threshold
 			$options{'factor'} && $eVal <= $options{'factor'} * $topEVal # within e-val factor
 		)
 		{
@@ -906,7 +1057,7 @@ sub classifyBlast
 			{
 				my $newTaxID = getTaxIDFromAcc($acc);
 				
-				if ( ! $newTaxID || ! defined $taxParents[$newTaxID] )
+				if ( ! $newTaxID || ! taxIDExists($newTaxID) )
 				{
 					$newTaxID = 1;
 				}
@@ -931,6 +1082,8 @@ sub classifyBlast
 		$lastQueryID = $queryID;
 	}
 	
+	close BLAST;
+	
 	if ( $zeroEVal )
 	{
 		ktWarn("\"$fileName\" had e-values of 0. Approximated log[10] of 0 as $minEVal.");
@@ -966,10 +1119,10 @@ sub getAccFromSeqID
 		$acc = (split /\|/, $acc)[3];
 	}
 	
-	if ( $acc !~ /^\d+$/ && $acc !~ /^[A-Z]+_?[A-Z]*\d+(\.\d+)?$/ )
+	if ( $acc !~ /^\d+$/ && $acc !~ /^[A-Z\d]+_?[A-Z\d]+(\.\d+)?$/ )
 	{
 		$invalidAccs{$acc} = 1;
-		return undef;
+		#return undef;
 	}
 	
 	return $acc;
@@ -1293,7 +1446,7 @@ sub htmlHeader
 			$notFound = "Could not get resources from \\\"$options{'url'}\\\".";
 		}
 		
-		$script = indent(2) . "<script src=\"$path$javascript\"></script>\n";
+		$script = indent(2) . "<script src=\"$path$javascript\" type=\"text/javascript\"></script>\n";
 	}
 	
 	return
@@ -1303,13 +1456,13 @@ sub htmlHeader
 			indent(2) . "<meta charset=\"utf-8\"/>\n" .
 #			indent(2) . "<base href=\"$path\" target=\"_blank\"/>\n" .
 			indent(2) . "<link rel=\"shortcut icon\" href=\"$path$favicon\"/>\n" .
-			indent(2) . "<script id=\"notfound\">window.onload=function(){document.body.innerHTML=\"$notFound\"}</script>\n" .
+			indent(2) . "<script id=\"notfound\" type=\"text/javascript\">window.onload=function(){document.body.innerHTML=\"$notFound\"}</script>\n" .
 			$script .
 		indent(1) . "</head>\n" .
 		indent(1) . "<body>\n" .
-			indent(2) . "<img id=\"hiddenImage\" src=\"$path$hiddenImage\" style=\"display:none\"/>\n" .
-			indent(2) . "<img id=\"loadingImage\" src=\"$path$loadingImage\" style=\"display:none\"/>\n" .
-			indent(2) . "<img id=\"logo\" src=\"$path$logo\" style=\"display:none\"/>\n" .
+			indent(2) . "<img id=\"hiddenImage\" src=\"$path$hiddenImage\" style=\"display:none\" alt=\"Hidden Image\"/>\n" .
+			indent(2) . "<img id=\"loadingImage\" src=\"$path$loadingImage\" style=\"display:none\" alt=\"Loading Indicator\"/>\n" .
+			indent(2) . "<img id=\"logo\" src=\"$path$logo\" style=\"display:none\" alt=\"Logo of Krona\"/>\n" .
 			indent(2) . "<noscript>Javascript must be enabled to view this page.</noscript>\n" .
 			indent(2) . "<div style=\"display:none\">\n";
 }
@@ -1514,7 +1667,7 @@ sub printWarnings
 	{
 		ktWarn
 		(
-			"The following accessions were not in a valid format and were ignored:\n" .
+			"The following accessions look strange and may yield erroneous results. Please check if they are acual valid NCBI accessions:\n" .
 			join ' ', (keys %invalidAccs)
 		);
 		
@@ -1616,6 +1769,19 @@ sub setOption
 	$options{$option} = $value;
 }
 
+sub shouldCollapse
+{
+	my ($taxID) = @_;
+	
+	return !
+	(
+		getTaxRank($taxID) ne 'no rank' ||
+		! $options{'noRank'} && $taxID != 131567 ||
+		$taxID == 1 ||
+		$options{'cellular'} && $taxID == 131567
+	);
+}
+
 sub taxContains
 {
 	# determines if $parent is an ancestor of (or equal to) $child
@@ -1918,7 +2084,7 @@ sub dataHeader
 		my $enableText = $supp ? " enable=\"$suppDir/$suppEnableFile\"" : '';
 		$header .= indent(4) . "<$memberTag$enableText>members</$memberTag>\n";
 		$assignedText = " ${memberTag}Node=\"members\"";
-		$summaryText = " ${memberTag}\All=\"members\"";
+		$summaryText = " ${memberTag}All=\"members\"";
 		
 		if ( $options{'postUrl'} )
 		{


=====================================
KronaTools/scripts/ClassifyHits.pl
=====================================
@@ -0,0 +1,136 @@
+#!/usr/bin/env perl
+
+# Copyright © 2017, National Human Genome Research Institute;
+# all rights reserved. Authored by: Brian Ondov
+#
+# See the LICENSE.txt file included with this software for license information.
+
+
+use strict;
+
+BEGIN
+{
+	use File::Basename;
+	use Cwd 'abs_path';
+	use lib dirname(abs_path($0)) . "/../lib";
+	use KronaTools;
+}
+
+my @options =
+qw(
+	out
+	thresholdGeneric
+	random
+	summarize
+);
+
+setOption('out', 'taxonomy.tab');
+
+getKronaOptions(@options);
+
+if
+(
+	@ARGV < 1
+)
+{
+	printUsage
+	(
+'Performs LCA (lowest common ancestor) based classification on groups of hits
+for queries.',
+		$KronaTools::argumentNames{'hits'},
+		$KronaTools::argumentDescriptions{'hits'},
+		0,
+		0,
+		\@options
+	);
+	printHeader('Output');
+	printColumns
+	(
+		'Default:',
+		'<queryID> <taxID> <score>',
+		'Summarized (-s):',
+		'<count> <taxID> <score>'
+	);
+	print "\n";
+	printColumns
+	(
+		'   queryID',
+		'The query ID as it appears in the input.',
+		'   taxID',
+'The NCBI taxonomy ID the query was assigned to (or -1 if it has no hits).',
+		'   score',
+'The score of the assignment(s); by default, the average E-value of "best" hits
+(see -p, -b).',
+		'   count',
+		'The number of assignments.'
+	);
+	print "\n";
+	
+	exit 0;
+}
+
+# load taxonomy
+
+print "Loading taxonomy...\n";
+loadTaxonomy();
+
+my %taxIDs;
+my %scores;
+
+# parse BLAST results
+
+foreach my $fileName (@ARGV)
+{
+	print "Classifying $fileName...\n";
+	classify($fileName, \%taxIDs, \%scores);
+}
+
+printWarnings();
+
+my $outFile = getOption('out');
+
+print "Writing $outFile...\n";
+
+open OUT, ">$outFile" or die "Could not open $outFile for writing";
+
+my $scoreName = getScoreName();
+
+if ( getOption('summarize') )
+{
+	my %magnitudes;
+	my %totalScores;
+	
+	print OUT "#count\ttaxID\t$scoreName\n";
+	
+	foreach my $queryID ( keys %taxIDs )
+	{
+		$magnitudes{$taxIDs{$queryID}}++;
+		$totalScores{$taxIDs{$queryID}} += $scores{$queryID};
+	}
+	
+	foreach my $taxID ( sort {$a <=> $b} keys %magnitudes )
+	{
+		print OUT join "\t",
+		(
+			$magnitudes{$taxID},
+			$taxID,
+			$totalScores{$taxID} / $magnitudes{$taxID}
+		), "\n";
+	}
+}
+else
+{
+	print OUT "#queryID\ttaxID\t$scoreName\n";
+	
+	foreach my $queryID ( sort keys %taxIDs )
+	{
+		print OUT "$queryID\t$taxIDs{$queryID}\t$scores{$queryID}\n";
+	}
+}
+
+close OUT;
+
+my $options = getOption('summarize') ? ' -m 1' : '';
+my $outFile = getOption('out');
+
+print "\nTo import, run:\n   ktImportTaxonomy$options $outFile\n\n";


=====================================
KronaTools/scripts/ImportBLAST.pl
=====================================
@@ -33,6 +33,7 @@ qw(
 	bitScore
 	combine
 	depth
+	cellular
 	noRank
 	hueBad
 	hueGood


=====================================
KronaTools/scripts/ImportHits.pl
=====================================
@@ -0,0 +1,167 @@
+#!/usr/bin/env perl
+
+# Copyright © 2011, Battelle National Biodefense Institute (BNBI);
+# all rights reserved. Authored by: Brian Ondov, Nicholas Bergman, and
+# Adam Phillippy
+#
+# See the LICENSE.txt file included with this software for license information.
+
+
+use strict;
+
+BEGIN
+{
+	use File::Basename;
+	use Cwd 'abs_path';
+	use lib dirname(abs_path($0)) . "/../lib";
+	use KronaTools;
+}
+
+# defaults
+#
+setOption('out', 'hits.krona.html');
+setOption('name', 'Root');
+
+my @options =
+qw(
+	out
+	name
+	thresholdGeneric
+	include
+	random
+	combine
+	depth
+	cellular
+	noRank
+	hueBad
+	hueGood
+	url
+	postUrl
+	taxonomy
+);
+
+getKronaOptions(@options);
+
+if
+(
+	@ARGV < 1
+)
+{
+	printUsage
+	(
+'Creates a Krona chart based on LCA (lowest common ancestor) classification of groups of hits
+for queries.',
+		$KronaTools::argumentNames{'hits'},
+		$KronaTools::argumentDescriptions{'hits'},
+		1,
+		1,
+		\@options
+	);
+	
+	exit 0;
+}
+
+my $tree = newTree();
+
+# load taxonomy
+
+print "Loading taxonomy...\n";
+loadTaxonomy();
+
+my $set = 0;
+my @datasetNames;
+my $useMag;
+
+foreach my $input (@ARGV)
+{
+	my ($fileName, $magFile, $name) = parseDataset($input);
+	
+	my %magnitudes;
+	my %taxIDs;
+	my %scores;
+	
+	if ( ! getOption('combine') )
+	{
+		push @datasetNames, $name;
+	}
+	
+	print "Importing $fileName...\n";
+	
+	# load magnitudes
+	
+	if ( defined $magFile )
+	{
+		print "   Loading magnitudes from $magFile...\n";
+		loadMagnitudes($magFile, \%magnitudes);
+		$useMag = 1;
+	}
+	
+	print "   Classifying hits...\n";
+	classify($fileName, \%taxIDs, \%scores);
+	
+	print "   Computing tree...\n";
+	
+	foreach my $queryID ( keys %taxIDs )
+	{
+		my $taxID = $taxIDs{$queryID};
+		
+		if ( $taxID == -1 )
+		{
+			if ( getOption('include') )
+			{
+				$taxID = 0;
+			}
+			else
+			{
+				next;
+			}
+		}
+		
+		addByTaxID
+		(
+			$tree,
+			$set,
+			$taxID,
+			$queryID,
+			$magnitudes{$queryID},
+			$scores{$queryID}
+		);
+	}
+	
+	if ( ! getOption('combine') )
+	{
+		$set++;
+	}
+}
+
+my @attributeNames =
+(
+	'magnitude',
+	'magnitudeUnassigned',
+	'count',
+	'unassigned',
+	'taxon',
+	'rank',
+	'score'
+);
+
+my @attributeDisplayNames =
+(
+	$useMag ? 'Magnitude' : undef,
+	$useMag ? 'Unassigned magnitude' : undef,
+	'Count',
+	'Unassigned',
+	'Tax ID',
+	'Rank',
+	'Avg. score',
+);
+
+writeTree
+(
+	$tree,
+	\@attributeNames,
+	\@attributeDisplayNames,
+	\@datasetNames,
+	getOption('hueBad'),
+	getOption('hueGood')
+);


=====================================
KronaTools/scripts/ImportMETAREP-blast.pl → KronaTools/scripts/ImportMETAREP-BLAST.pl
=====================================
@@ -29,6 +29,7 @@ qw(
 	bitScore
 	combine
 	depth
+	cellular
 	noRank
 	hueBad
 	hueGood


=====================================
KronaTools/scripts/ImportTaxonomy.pl
=====================================
@@ -31,6 +31,7 @@ qw(
 	scoreCol
 	magCol
 	depth
+	cellular
 	noRank
 	hueBad
 	hueGood


=====================================
KronaTools/scripts/accession2taxid.make
=====================================
@@ -2,9 +2,7 @@ ACC2TAXID=\
 	dead_nucl.accession2taxid \
 	dead_prot.accession2taxid \
 	dead_wgs.accession2taxid \
-	nucl_est.accession2taxid \
 	nucl_gb.accession2taxid \
-	nucl_gss.accession2taxid \
 	nucl_wgs.accession2taxid \
 	prot.accession2taxid
 


=====================================
KronaTools/src/krona-2.0.js
=====================================
@@ -756,7 +756,7 @@ function Node()
 		
 //		if ( this.alphaWedge.current() > 0 || this.alphaLabel.current() > 0 )
 		{
-			var lastChildAngleEnd;
+			var lastChildAngleEnd = angleStartCurrent;
 			
 			if ( this.hasChildren() )//canDisplayChildren )
 			{
@@ -774,7 +774,7 @@ function Node()
 					angleEndCurrent == this.parent.angleEnd.current() + rotationOffset
 				);
 				
-				if ( angleStartCurrent != angleEndCurrent )
+				//if ( angleStartCurrent != angleEndCurrent )
 				{
 					this.drawLines(angleStartCurrent, angleEndCurrent, radiusInner, drawRadial, selected);
 				}
@@ -785,7 +785,9 @@ function Node()
 				if ( this == selectedNode || alphaOtherCurrent )
 				{
 					childRadiusInner =
-						this.children[this.children.length - 1].radiusInner.current() * gRadius;
+						this.children.length ?
+							this.children[this.children.length - 1].radiusInner.current() * gRadius
+						: radiusInner
 				}
 				
 				if ( this == selectedNode )
@@ -938,7 +940,7 @@ function Node()
 					var lastChildAngle;
 					var truncateWedge =
 					(
-						this.hasChildren() &&
+						(this.hasChildren() || this == selectedNode ) &&
 						! this.keyed &&
 						(compress || depth < maxDisplayDepth) &&
 						drawChildren
@@ -946,7 +948,7 @@ function Node()
 					
 					if ( truncateWedge )
 					{
-						radiusOuter = this.children[0].radiusInner.current() * gRadius;
+						radiusOuter = this.children.length ? this.children[0].radiusInner.current() * gRadius : radiusInner;
 					}
 					else
 					{
@@ -969,7 +971,7 @@ function Node()
 					*/
 					context.globalAlpha = alphaWedgeCurrent;
 					
-					if ( radiusInner != radiusOuter )
+					if ( radiusInner != radiusOuter || truncateWedge )
 					{
 						drawWedge
 						(
@@ -2146,17 +2148,24 @@ function Node()
 	
 	this.getUnclassifiedPercentage = function()
 	{
-		var lastChild = this.children[this.children.length - 1];
+		if ( this.children.length )
+		{
+			var lastChild = this.children[this.children.length - 1];
 		
-		return getPercentage
-		(
+			return getPercentage
 			(
-				this.baseMagnitude +
-				this.magnitude -
-				lastChild.magnitude -
-				lastChild.baseMagnitude
-			) / this.magnitude
-		) + '%';
+				(
+					this.baseMagnitude +
+					this.magnitude -
+					lastChild.magnitude -
+					lastChild.baseMagnitude
+				) / this.magnitude
+			) + '%';
+		}
+		else
+		{
+			return '100%';
+		}
 	}
 	
 	this.getUnclassifiedText = function()
@@ -2982,15 +2991,19 @@ function Node()
 		if ( this == selectedNode )
 		{
 			var otherArc = 
-				angleFactor *
-				(
-					this.baseMagnitude + this.magnitude -
-					lastChild.baseMagnitude - lastChild.magnitude
-				);
+				this.children.length ?
+					angleFactor *
+					(
+						this.baseMagnitude + this.magnitude -
+						lastChild.baseMagnitude - lastChild.magnitude
+					)
+				: this.baseMagnitude + this.magnitude;
 			this.canDisplayLabelOther =
-				otherArc *
-				(this.children[0].radiusInner.end + 1) * gRadius >=
-				minWidth();
+				this.children.length ?
+					otherArc *
+					(this.children[0].radiusInner.end + 1) * gRadius >=
+					minWidth()
+				: true;
 			
 			this.keyUnclassified = false;
 			
@@ -3006,7 +3019,16 @@ function Node()
 			
 			this.angleStart.setTarget(0);
 			this.angleEnd.setTarget(Math.PI * 2);
-			this.radiusInner.setTarget(0);
+			
+			if ( this.children.length )
+			{
+				this.radiusInner.setTarget(0);
+			}
+			else
+			{
+				this.radiusInner.setTarget(compressedRadii[0]);
+			}
+			
 			this.hidePrev = this.hide;
 			this.hide = false;
 			this.hideAlonePrev = this.hideAlone;
@@ -3557,7 +3579,7 @@ value="↔" title="Expand this wedge to become the new focus of the chart"/><
 	position = addOptionElement
 	(
 		position,
-'<a style="margin:2px" target="_blank" href="https://github.com/marbl/Krona/wiki"><img style="vertical-align:middle;width:108px;height:30px;" src="' + logoImage + '"/></a><input type="button" id="back" value="←" title="Go back (Shortcut: ←)"/>\
+'<a style="margin:2px" target="_blank" href="https://github.com/marbl/Krona/wiki"><img style="vertical-align:middle;width:108px;height:30px;" src="' + logoImage + '" alt="Logo of Krona"/></a><input type="button" id="back" value="←" title="Go back (Shortcut: ←)"/>\
 <input type="button" id="forward" value="→" title="Go forward (Shortcut: →)"/> \
  Search: <input type="text" id="search"/>\
 <input id="searchClear" type="button" value="x" onclick="clearSearch()"/> \
@@ -3855,7 +3877,7 @@ function checkSelectedCollapse()
 		newNode = newNode.children[0];
 	}
 	
-	if ( newNode.children.length == 0 )
+	if ( newNode.children.length == 0 && newNode.getParent() )
 	{
 		newNode = newNode.getParent();
 	}
@@ -5738,18 +5760,10 @@ function setCallBacks()
 	}
 	
 	image = document.getElementById('hiddenImage');
-	
-	if ( image.complete )
+	image.onload = function()
 	{
 		hiddenPattern = context.createPattern(image, 'repeat');
 	}
-	else
-	{
-		image.onload = function()
-		{
-			hiddenPattern = context.createPattern(image, 'repeat');
-		}
-	}
 	
 	var loadingImageElement = document.getElementById('loadingImage');
 	
@@ -5823,8 +5837,8 @@ function setFocus(node)
 	}
 	
 	var table = '<table>';
-	
-	table += '<tr><td></td></tr>';
+	//TODO: use CSS margins instead of an additional column
+	table += '<tr><td></td><td></td></tr>';
 	
 	for ( var i = 0; i < node.attributes.length; i++ )
 	{
@@ -6056,24 +6070,9 @@ function snapshot()
 	
 	svg += svgFooter();
 	
-	snapshotWindow = window.open
-	(
-		'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg),
-		'_blank'
-	);
-/*	var data = window.open('data:text/plain;charset=utf-8,hello', '_blank');
-	var data = window.open('', '_blank');
-	data.document.open('text/plain');
-	data.document.write('hello');
-	data.document.close();
-	var button = document.createElement('input');
-	button.type = 'button';
-	button.value = 'save';
-	button.onclick = save;
-	data.document.body.appendChild(button);
-//	snapshotWindow.document.write(svg);
-//	snapshotWindow.document.close();
-*/	
+	var snapshotWindow = window.open('', '_blank', '', 'replace=false');
+	snapshotWindow.document.write('<html><body><a href="data:image/svg+xml,' + encodeURIComponent(svg) + '" download="snapshot.svg">Download Snapshot</a></html></body>');
+	snapshotWindow.document.write(svg);
 }
 
 function save()
@@ -6570,7 +6569,7 @@ function updateView()
 
 function updateMaxAbsoluteDepth()
 {
-	while ( selectedNode.depth > maxAbsoluteDepth - 1 )
+	while ( maxAbsoluteDepth > 1 && selectedNode.depth > maxAbsoluteDepth - 1 )
 	{
 		selectedNode = selectedNode.getParent();
 	}


=====================================
KronaTools/updateTaxonomy.sh
=====================================
@@ -13,6 +13,13 @@ else # Assume linux
     MD5=md5sum
 fi
 
+# This would not resolve symlink:
+# ktPath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )"
+# Therefore this:
+# perl function to resolve symlinks that will function on Linux and OSX (since 'readlink -f' is different under OSX)
+readlink_f(){ perl -MCwd -e 'print Cwd::abs_path shift' "$1";}
+ktPath=$(dirname $(readlink_f $0))
+
 makefileAcc2taxid="scripts/accession2taxid.make"
 makefileTaxonomy="scripts/taxonomy.make"
 
@@ -147,8 +154,6 @@ then
 	die "Cannot use --only-fetch with --only-build."
 fi
 
-ktPath="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )"
-
 if [ "$taxonomyPath" == "" ]
 then
 	taxonomyPath="$ktPath/taxonomy";
@@ -175,7 +180,7 @@ fi
 
 if [ "$accessions" == "1" ] && [ ! -d "$taxonomyPath/accession2taxid" ]
 then
-	mkdir "$taxonomyPath/accession2taxid"
+	mkdir -p "$taxonomyPath/accession2taxid"
 
 	if [ "$?" != "0" ]
 	then
@@ -194,9 +199,7 @@ ACC2TAXID="
 accession2taxid/dead_nucl.accession2taxid
 accession2taxid/dead_prot.accession2taxid
 accession2taxid/dead_wgs.accession2taxid
-accession2taxid/nucl_est.accession2taxid
 accession2taxid/nucl_gb.accession2taxid
-accession2taxid/nucl_gss.accession2taxid
 accession2taxid/nucl_wgs.accession2taxid
 accession2taxid/prot.accession2taxid
 "



View it on GitLab: https://salsa.debian.org/med-team/radiant/commit/349eb89bb158d3ead8575c4c4bcc783ad77094b1

-- 
View it on GitLab: https://salsa.debian.org/med-team/radiant/commit/349eb89bb158d3ead8575c4c4bcc783ad77094b1
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20190717/7c439ebb/attachment-0001.html>


More information about the debian-med-commit mailing list