[Bio] / FigWebServices / genome_statistics.cgi Repository:
ViewVC logotype

View of /FigWebServices/genome_statistics.cgi

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.22 - (download) (annotate)
Wed Aug 10 16:17:52 2005 UTC (14 years, 7 months ago) by overbeek
Branch: MAIN
Changes since 1.21: +4 -4 lines
fixes to showing reactions

# -*- perl -*-
#### start ####

use FIG;
my $fig = new FIG;

use HTML;
use strict;
use CGI;
my $cgi = new CGI;

if (0)
{
    my $VAR1;
    eval(join("",`cat /tmp/statistics_parms`));
    $cgi = $VAR1;
#   print STDERR &Dumper($cgi);
}

if (0)
{
    print $cgi->header;
    my @params = $cgi->param;
    print "<pre>\n";
    foreach $_ (@params)
    {
	print "$_\t:",join(",",$cgi->param($_)),":\n";
    }

    if (0)
    {
	if (open(TMP,">/tmp/statistics_parms"))
	{
	    print TMP &Dumper($cgi);
	    close(TMP);
	}
    }
    exit;
}

my $html = [];
unshift @$html, "<TITLE>The SEED Statistics Page</TITLE>\n";

my @genomes = $cgi->param('genome');
my $request = $cgi->param('request');

if ($request eq "subsystems_summary")
{
    &subsys_summary($fig,$cgi,$html);
}
elsif ($request eq "edit_kv_stats") {
    &edit_kv_stats($fig,$cgi,$html, $cgi->param('genome'));
}
elsif ((@genomes == 0) && (! $request))
{
    &table_of_genomes($fig,$cgi,$html);
}
elsif (! $request)
{
    my $genome;
    foreach $genome (@genomes)
    {
	&basic_stats($fig,$cgi,$html,$genome);
	push(@$html,$cgi->hr);
	&assignment_stats($fig,$cgi,$html,$genome);
	push(@$html,$cgi->hr);
	&kv_peg_stats($fig, $cgi, $html, $genome);
	push(@$html,$cgi->hr);
	&kv_stats($fig, $cgi, $html, $genome);
	my $user = $cgi->param('user');
	push(@$html,"<a href=./genome_statistics.cgi?genome=$genome&request=show_subsystems&user=$user>Show Subsystems</a><br>\n");
	push(@$html,"<a href=./genome_statistics.cgi?genome=$genome&request=show_reactions&user=$user>Show Reactions</a><br>\n");
	push(@$html,$cgi->br);
    }
}
elsif (@genomes == 0)
{
    push(@$html,"<h1>Sorry, you need to specify at least one valid genome</h1>\n");
}
else
{
    if    ($request eq "hypo_sub")          { &handle_hypo_sub($fig,$cgi,$html,$genomes[0]) }
    elsif ($request eq "hypo_nosub")        { &handle_hypo_nosub($fig,$cgi,$html,$genomes[0]) }
    elsif ($request eq "nothypo_sub")       { &handle_nothypo_sub($fig,$cgi,$html,$genomes[0]) }
    elsif ($request eq "nothypo_nosub")     { &handle_nothypo_nosub($fig,$cgi,$html,$genomes[0]) }
    elsif ($request eq "show_subsystems")   { &handle_show_subsystems($fig,$cgi,$html,$genomes[0]) }
    elsif ($request eq "show_reactions")    { &handle_show_reactions($fig,$cgi,$html,$genomes[0]) }
    else
    {
	push(@$html,$cgi->h1("Invalid request: $request"));
    }
}
&HTML::show_page($cgi,$html);
exit;


#  Only subroutines below


sub basic_stats {
    my($fig,$cgi,$html,$genome) = @_;

    my($gname,$szdna,$num_contigs,$pegs,$rnas,$taxonomy) = &get_basic_stats($fig,$genome);
    push @$html, $cgi->h1('Basic Statistics'), "\n",
	             "<b>Genome ID:</b> $genome", $cgi->br, "\n",
	             "<b>Name:</b> $gname", $cgi->br, "\n",
	             "<b>Size (bp):</b> $szdna", $cgi->br, "\n",
	             "<b>Number contigs:</b> $num_contigs", $cgi->br, "\n",
	             "<b>Number CDSs:</b> $pegs", $cgi->br, "\n",
	             "<b>Number rnas:</b> $rnas", $cgi->br, "\n",
	             "<b>Taxonomy:</b> $taxonomy", $cgi->br, "\n";
    push @$html, project_description( $genome );
    return
}


sub project_description {
    ( my $genome = shift @_ ) or return ();
    -d $FIG_Config::organisms && -d "$FIG_Config::organisms/$genome"
                              && -f "$FIG_Config::organisms/$genome/PROJECT"
                              || return ();
    open( PROJECT, "<$FIG_Config::organisms/$genome/PROJECT" ) || return ();
    my @project = <PROJECT>;
    close PROJECT;
    return ( "<b>Project description:</b>\n<pre>",
             ( map { "    " . $_ } @project ),
             "</pre>\n"
           );
}


sub commify {
    my($n) = @_;
    my(@n) = ();
    my($i);

    for ($i = (length($n) - 3); ($i > 0); $i -= 3)
    {
	unshift(@n,",",substr($n,$i,3));
    }
    unshift(@n,substr($n,0,$i+3));
    return join("",@n);
}

sub assignment_stats {
    my($fig,$cgi,$html,$genome) = @_;

    my $rdbH = $fig->db_handle;
    
    my $hypo_sub = 0;
    my $hypo_nosub = 0;
    my $nothypo_sub = 0;
    my $nothypo_nosub = 0;

    my($subsystem_data,$assignments_data) = &get_data($fig,$cgi,$genome);
    my %in = map { $_->[2] => 1 } @$subsystem_data;
    my $in = keys(%in);

    foreach $_ (@$assignments_data)
    {
	my($peg,$func) = @$_;
	my $is_hypo = &FIG::hypo($func);

	if    ($is_hypo && $in{$peg})           { $hypo_sub++ }
	elsif ($is_hypo && ! $in{$peg})         { $hypo_nosub++ }
	elsif ((! $is_hypo) && (! $in{$peg}))   { $nothypo_nosub++ }
	elsif ((! $is_hypo) && $in{$peg})       { $nothypo_sub++ }
    }
    my $tot = $hypo_sub + $nothypo_sub + $hypo_nosub + $nothypo_nosub;
    my $fracHS = sprintf "%4.2f", $hypo_sub / $tot;
    my $fracNHS = sprintf "%4.2f", $nothypo_sub / $tot;
    my $fracHNS = sprintf "%4.2f", $hypo_nosub / $tot;
    my $fracNHNS = sprintf "%4.2f", $nothypo_nosub / $tot;
    
    my $user = $cgi->param('user');

    push @$html, "<table>\n",
                 "  <tr>\n",
                 "    <th align=left>PEGs with hypothetical functions and in subsystem:</th>\n",
                 "    <td align=right><a href=./genome_statistics.cgi?user=$user&genome=$genome&request=hypo_sub>$hypo_sub ($fracHS)</a></td>\n",
                 "  </tr>\n",
                 "  <tr>\n",
                 "    <th align=left>PEGs with nonhypothetical functions and in subsystem:</th>\n",
                 "    <td align=right><a href=./genome_statistics.cgi?user=$user&genome=$genome&request=nothypo_sub>$nothypo_sub ($fracNHS)</a></td>\n",
                 "  </tr>\n",
                 "  <tr>\n",
                 "    <th align=left>PEGs with hypothetical functions and not in subsystem:</th>\n",
                 "    <td align=right><a href=./genome_statistics.cgi?user=$user&genome=$genome&request=hypo_nosub>$hypo_nosub ($fracHNS)</a></td>\n",
                 "  </tr>\n",
                 "  <tr>\n",
                 "    <th align=left>PEGs with nonhypothetical functions and not in subsystem:</th>\n",
                 "    <td align=right><a href=./genome_statistics.cgi?user=$user&genome=$genome&request=nothypo_nosub>$nothypo_nosub ($fracNHNS)</a></td>\n",
                 "  </tr>\n",
                 "</table>\n";
}

sub handle_show_subsystems {
    my($fig,$cgi,$html,$genome) = @_;
    my(%in,$sub,$role,$protein,$sub_link,$tuple,$categories);

    my($subsystem_data,$assignments_data) = &get_data($fig,$cgi,$genome);
    foreach $_ (@$subsystem_data)
    {
	($sub,$role,$protein) = @$_;
	push(@{$in{$sub}->{$role}},&HTML::fid_link($cgi,$protein,0) . ": " . scalar $fig->function_of($protein));
    }

    my @subs = sort { ($a->[0] cmp $b->[0]) or
		      ($a->[1] cmp $b->[1]) or
		      ($a->[2] cmp $b->[2]) or
		      ($a->[3] cmp $b->[3]) or
		      ($a->[4] cmp $b->[4]) 
		    } 
               map { $sub = $_; 
		     $categories = $fig->subsystem_classification($sub);
		     $categories = ((@$categories > 0) && $categories->[0]) ? $categories : ["Misc"];
		     [@$categories,$sub] 
		   }
       keys(%in);

    my $last1 = "";
    my $last2 = "";
    foreach $tuple (@subs)
    {
	$sub = pop @{$tuple};
	my $topic = $tuple->[0];

	if ($topic ne $last1)
	{
	    push(@$html,$cgi->h1($topic));
	    $last1 = $topic;
	    $last2 = "";
	}

	$topic = $tuple->[1] ? $tuple->[1] : "";
	if ($topic && ($topic ne $last2))
	{
	    push(@$html,$cgi->h2($topic));
	    $last2 = $topic;
	}

	$sub_link = &sub_link($cgi,$sub);
	push(@$html,$cgi->h3($sub_link));

	my $roles = [];
	foreach $role (sort keys(%{$in{$sub}}))
	{
	    push(@$roles,$cgi->ul($cgi->li($in{$sub}->{$role})));
	}
	push(@$html,$cgi->ul($cgi->li($roles)));
    }
}

sub handle_show_reactions {
    my($fig,$cgi,$html,$genome) = @_;
    my($react_for_role,$r,%topic,%reaction,$sub,$role,$protein,$sub_link,$tuple,$categories);
    my(%reactions_for_sub,%class,$reactions,$classL,$category);

    my($subsystem_data,$assignments_data) = &get_data($fig,$cgi,$genome);
    foreach $_ (@$subsystem_data)
    {
	($sub,$role,$protein) = @$_;
	if (! defined($reactions_for_sub{$sub}))
	{
	    my $subsystem = new Subsystem($sub,$fig,0);
	    $reactions = $subsystem->get_reactions;
	    $reactions = $reactions ? $reactions : "";
	    $reactions_for_sub{$sub} = $reactions;
	    $class{$sub} = $fig->subsystem_classification($sub);
	}
	
	if (($reactions = $reactions_for_sub{$sub}) && ($react_for_role = $reactions->{$role}))
	{
	    $classL = $class{$sub};
	    $category = ((@$classL > 0) && $classL->[0]) ? $classL->[0] : "Misc";
	    foreach $r (@$react_for_role)
	    {
		$reaction{$r}->{$protein} = 1;
		$topic{$category}->{$r} = 1;
	    }
	}
    }

    my @all       = sort { $a cmp $b } keys(%topic);
    foreach $category (@all)
    {
	&show_class_react($fig,$cgi,$html,$category,[keys(%{$topic{$category}})],\%reaction);
    }

    if ($_ = $topic{"Misc"})
    {
	&show_class_react($fig,$cgi,$html,'Misc',[keys(%$_)],\%reaction);
    }
}

sub show_class_react {
    my($fig,$cgi,$html,$class,$for_topic,$reaction) = @_;
    my($r,@pegs,$peg);

    push(@$html,$cgi->h1($class));
    foreach $r (sort @$for_topic)
    {
	my $disp_react = $fig->displayable_reaction($r);
	$disp_react =~ s/^R\d+\: //;

	my $rstring = &HTML::reaction_link($r) . ": $disp_react";
	push(@$html,$cgi->h2($rstring),"\n");
	@pegs = sort { &FIG::by_fig_id($a,$b) } keys(%{$reaction->{$r}});
	push(@$html,"<ul>\n");
	foreach $peg (@pegs)
	{
	    push(@$html,"<li>" . &HTML::fid_link($cgi,$peg) . " " . scalar $fig->function_of($peg) . "\n");
	}
	push(@$html,"</ul>\n");
    }
}	

sub handle_hypo_sub {
    my($fig,$cgi,$html,$genome) = @_;

    my($subsystem_data,$assignments_data) = &get_data($fig,$cgi,$genome);
    my %subs = map { $_->[2] => $_->[0] } @$subsystem_data;
    my $col_hdrs = ["PEG","Function","Subsystem"];
    my $tab = [];
    foreach $_ (@$assignments_data)
    {
	my($peg,$func) = @$_;
	if (&FIG::hypo($func) && ($subs{$peg}))
	{
	    push(@$tab,[&HTML::fid_link($cgi,$peg,0),$func,&sub_link($cgi,$subs{$peg})]);
	}
    }
    $_ = @$tab;
    push(@$html,&HTML::make_table($col_hdrs,$tab,"$_ Hypothetical Pegs in Subsystems"));
}

sub handle_hypo_nosub {
    my($fig,$cgi,$html,$genome) = @_;

    my($subsystem_data,$assignments_data) = &get_data($fig,$cgi,$genome);
    my %subs = map { $_->[2] => $_->[0] } @$subsystem_data;
    my $col_hdrs = ["PEG","Function"];
    my $tab = [];
    foreach $_ (@$assignments_data)
    {
	my($peg,$func) = @$_;
	if (&FIG::hypo($func) && (! $subs{$peg}))
	{
	    push(@$tab,[&HTML::fid_link($cgi,$peg,0),$func]);
	}
    }
    $_ = @$tab;
    push(@$html,&HTML::make_table($col_hdrs,$tab,"$_ Hypothetical Pegs NOT in Subsystems"));
}

sub handle_nothypo_sub {
    my($fig,$cgi,$html,$genome) = @_;

    my($subsystem_data,$assignments_data) = &get_data($fig,$cgi,$genome);
    my %subs = map { $_->[2] => $_->[0] } @$subsystem_data;
    my $col_hdrs = ["PEG","Function","Subsystem"];
    my $tab = [];
    foreach $_ (@$assignments_data)
    {
	my($peg,$func) = @$_;
	if ((! &FIG::hypo($func)) && ($subs{$peg}))
	{
	    push(@$tab,[&HTML::fid_link($cgi,$peg,0),$func,&sub_link($cgi,$subs{$peg})]);
	}
    }
    $_ = @$tab;
    push(@$html,&HTML::make_table($col_hdrs,$tab,"$_ Nonhypothetical Pegs in Subsystems"));
}

sub handle_nothypo_nosub {
    my($fig,$cgi,$html,$genome) = @_;

    my($subsystem_data,$assignments_data) = &get_data($fig,$cgi,$genome);
    my %subs = map { $_->[2] => $_->[0] } @$subsystem_data;
    my $col_hdrs = ["PEG","Function"];
    my $tab = [];
    foreach $_ (@$assignments_data)
    {
	my($peg,$func) = @$_;
	if ((! &FIG::hypo($func)) && (! $subs{$peg}))
	{
	    push(@$tab,[&HTML::fid_link($cgi,$peg,0),$func]);
	}
    }
    $_ = @$tab;
    push(@$html,&HTML::make_table($col_hdrs,$tab,"$_ Nonhypothetical Pegs NOT in Subsystems"));
}

sub get_data {
    my($fig,$cgi,$genome) = @_;

    my $rdbH = $fig->db_handle;
    my $subsystem_data = $rdbH->SQL("SELECT DISTINCT subsystem,role,protein FROM subsystem_index WHERE ( protein like 'fig\|$genome.peg.%')");
    my $assignment_data = $rdbH->SQL("SELECT prot,assigned_function FROM assigned_functions WHERE ( prot like 'fig\|$genome.peg.%' AND made_by = 'master' )");

    return ($subsystem_data,$assignment_data);
}

sub sub_link {
    my($cgi,$sub) = @_;

    my $user = $cgi->param('user');
    $user = defined($user) ? $user : "";
    my $sub_link = "<a href=./subsys.cgi?ssa_name=$sub&request=show_ssa&user=$user>$sub</a>";

    return $sub_link;
}

sub get_basic_stats {
    my($fig,$genome) = @_;

    my $rdbH = $fig->db_handle;
    my $relational_db_response = $rdbH->SQL("SELECT gname,szdna,pegs,rnas,taxonomy FROM genome WHERE genome = '$genome'");
    my($gname,$szdna,$pegs,$rnas,$taxonomy) = @{$relational_db_response->[0]};
    my $szdna = &commify($szdna);
    my $num_contigs = scalar $fig->all_contigs($genome);
    return ($gname,$szdna,$num_contigs,$pegs,$rnas,$taxonomy);
}

sub table_of_genomes {
    my($fig,$cgi,$html) = @_;
    my(@genomes);

    push(@$html,"<pre>\n");
    if ($cgi->param('complete'))
    {
	@genomes = $fig->genomes("complete");
    }
    else
    {
	@genomes = $fig->genomes;
    }

    my $genome;
    push(@$html,join("\t","Genome ID","Complete","Genome Name","Size (bp)","Number Contigs","CDSs","RNAs","Taxonomy") . "\n");
    my $genome;
    foreach $genome (@genomes)
    {
	push(@$html,join("\t",($genome,$fig->is_complete($genome),&get_basic_stats($fig,$genome))) . "\n");
    }
    push(@$html,"</pre>\n");
}

	
sub subsys_summary {
    my($fig,$cgi,$html) = @_;
    my($Nsubs,$genome,$sub,$role,$peg,$genome_instances,%genomes_in_use,$peg_instances,%pegs_in_use);
    foreach $sub ($fig->all_subsystems)
    {
	$Nsubs++;
	foreach $genome (map { $_->[0] } @{$fig->subsystem_genomes($sub)})
	{
	    $genome_instances++;
	    $genomes_in_use{$genome}++;
	    foreach $role ($fig->subsystem_to_roles($sub))
	    {
		foreach $peg ($fig->pegs_in_subsystem_cell($sub,$genome,$role))
		{
		    $peg_instances++;
		    $pegs_in_use{$peg}++;
		}
	    }
	}
    }
    my $Ngenomes = scalar keys(%genomes_in_use);
    my $Npegs    = scalar keys(%pegs_in_use);
    my $g_in_sub = int($genome_instances / $Nsubs);
    my $p_in_sub = int($peg_instances / $Nsubs);
    push(@$html,$cgi->h1('Subsystem Summary'));
    push(@$html,$cgi->br,
	        "<b>Number Subsystems:</b> $Nsubs",$cgi->br,
	        "<b>Genomes in Subsystems:</b> $Ngenomes",$cgi->br,
	        "<b>PEGs in Subsystems:</b> $Npegs",$cgi->br,
	        "<b>Avg genomes per subsystem:</b> $g_in_sub",$cgi->br,
	        "<b>Avg PEGs per subsystem:</b> $p_in_sub",$cgi->br
	 );
    return
   
}

sub kv_peg_stats {
 my ($fig, $cgi, $html, $genome)=@_;
 
 #RAE Added the coverage of each genome with different attributes for the PEGs to find the number of genes that are in pirsf, etc
 push(@$html, "\n<div class=\"pegattributes\">\n<p><h2>PEG Attributes for ", $fig->genus_species($genome), "</h2></p>\n");
 
 my $pegtags=$fig->get_tags('peg');
 foreach my $type (sort {$a cmp $b} keys %$pegtags)
 {
   my @result = grep {$_ =~ /$genome/} @{$pegtags->{$type}};
   push(@$html, "\nPEGS with tag:  $type  :  ", scalar(@result), $cgi->br, "\n");
 }
} 

sub kv_stats {
 my ($fig, $cgi, $html, $genome, $edit)=@_;

 # RAE Added tables for key value pairs for an organism, and allow you to edit them
 # figure out kv's for the organism, and make a table with them
 
 # if the optional edit boolean is set and a user is supplied, we will make a table where you can edit the KV pairs
 # else we will just make a blank table
 
 # prepare the html so we can add form fields here
 push(@$html, "\n<div class=\"attributes\">\n<p><h2>Attributes for ", $fig->genus_species($genome), "</h2></p>\n");
 if ($edit) {push(@$html, $cgi->start_form(-action=>"genome_statistics.cgi"))}

 
 my $tab=[];
 my $user=$cgi->param('user');
 my $col_hdrs=["Attribute", "Value"];
 if ($user && $edit) {$col_hdrs=["Attribute", "Value", "URL"]}

 my $known;
 foreach my $key (sort {$a->[1] cmp $b->[1]} $fig->get_attributes($genome)) {
  $known->{$key->[1]}=1;
  if ($user && $edit) {
   push @$tab, 
    [
       $key->[1], 
       $cgi->textfield(-name=>"value.".$key->[1], -default=>$key->[2], -size=>50), 
       $cgi->textfield(-name=>"url.".$key->[1], -default=>$key->[3], -size=>50),
    ];
  } else {
   if ($key->[3] && $key->[3] =~ /^http/) {$key->[2] = "<a href=\"" . $key->[3] . "\">". $key->[2] . "</a>"}
   push @$tab, 
    [
       $key->[1], 
       $key->[2],
    ];
   }
  }


 if ($edit) {
  # now we want to add some pull down menus for things that we can add. And some blank boxes too for free text entry.
  # start with three of each
  my $opt=$fig->get_tags("genome"); # all the tags we know about
  my @options=sort {uc($a) cmp uc($b)} grep {!$known->{$_}} keys %$opt;
  unshift(@options, undef); # a blank field at the start
  for (my $i=1; $i<= (scalar @options + 5); $i++) {
   
   # we have the options, and 5 blank fields for free text entry
   my $choice=$cgi->popup_menu(-name=>"key.$i", -values=>\@options);
   if ($i >= scalar @options) {$choice = $cgi->textfield(-name=>"key.$i", -size=>50)}
   push @$tab, 
     [  
        $choice,
	$cgi->textfield(-name=>"value.$i", -size=>50), 
        $cgi->textfield(-name=>"url.$i", -size=>50),
     ];
  }
  # we need to know how many possibilities we have to look through later. Just pass it as a hidden, rather than counting it next time
  push(@$html, $cgi->hidden(-name=>"max new keys", -value=>scalar @options + 5));
 }

 # now just write the html
 push(@$html,&HTML::make_table($col_hdrs,$tab,"Attributes"));
 if ($edit) {
  push(@$html, $cgi->hidden("genome"), $cgi->hidden("user"), $cgi->hidden("request"));
  push(@$html, $cgi->submit('Change'), $cgi->reset());
 }
 else {
  push(@$html,"<p><a href=./genome_statistics.cgi?genome=$genome&request=edit_kv_stats&change=0&user=$user>Edit Key Value Pairs</a></p>\n</div>\n");
 }
} 


sub edit_kv_stats {
 my ($fig, $cgi, $html, $genome)=@_;
 if ($cgi->param("Change")) {
  # we have changed the values
  # get the old kv pairs so we can see what has changed
  my $changed; my $deleted;
  foreach my $key ($fig->get_attributes($genome)) {
   if (!$cgi->param('value.'.$key->[1]) && !$cgi->param('url.'.$key->[1])) {
    $fig->delete_attribute($genome, $key->[1]);
    push @$key, ["deleted", "td colspan=2 style=\"text-align: center\""];
    push @$deleted, $key;
   }
   elsif (($cgi->param('value.'.$key->[1]) ne $key->[2]) || ($cgi->param('url.'.$key->[1]) ne $key->[3]))  {
     $fig->change_attribute($genome, $key->[1], $cgi->param('value.'.$key->[1]), $cgi->param('url.'.$key->[1]));
     push @$key, $cgi->param('value.'.$key->[1]), $cgi->param('url.'.$key->[1]);
     push @$changed, $key;
   }
  }
  
  my $added;
  for (my $i=0; $i <= $cgi->param("max new keys"); $i++) {
   if ($cgi->param("key.$i")) {
    $fig->add_attribute($genome, $cgi->param("key.$i"), $cgi->param("value.$i"), $cgi->param("url.$i"));
    push @$added, [$cgi->param("key.$i"), ["added", "td colspan=2 style=\"text-align: center\""], $cgi->param("value.$i"), $cgi->param("url.$i")];
   }
  }

  # now all we have to do is create a table to report what we have done.
  my $tab=[];
  push (@$html, "<div class=\"altered\"><p><h2>Attributes Altered for ", $fig->genus_species($genome), " ($genome)</h2></p>");
  my $col_hdrs=["Attribute", "Original Value", "Original URL", "New Value", "New URL"];
  if ($changed) {push @$tab, [["<strong>Changed Attributes", "td colspan=5 bgcolor=gray style=\"text-align: center\""]], @$changed}
  if ($deleted) {push @$tab, [["<strong>Deleted Attributes", "td colspan=5 bgcolor=gray style=\"text-align: center\""]], @$deleted}
  if ($added)   {push @$tab, [["<strong>Added Attributes",   "td colspan=5 bgcolor=gray style=\"text-align: center\""]], @$added}
  
  push(@$html,&HTML::make_table($col_hdrs,$tab,"Changed Data"));
 }
 else {
  return kv_stats($fig, $cgi, $html, $genome, 1);
 }
}


MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3