[Bio] / SubsystemEditor / WebPage / MetaSpreadsheet.pm Repository:
ViewVC logotype

View of /SubsystemEditor/WebPage/MetaSpreadsheet.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (download) (as text) (annotate)
Tue Jul 1 14:42:49 2008 UTC (11 years, 6 months ago) by bartels
Branch: MAIN
looking at a meta spreadsheet

package SubsystemEditor::WebPage::MetaSpreadsheet;

use strict;
use warnings;
use URI::Escape;
use HTML;
use Data::Dumper;
use DBMaster;

use FIG;

use MIME::Base64;
use Data::Dumper;
use File::Spec;
use GenomeLists;
use MetaSubsystem;
use base qw( WebPage );

1;


##############################################################
# Method for registering components etc. for the application #
##############################################################
sub init {
  my ( $self ) = @_;

  $self->application->register_component( 'Table', 'SubsystemSpreadsheet' );
  $self->application->register_component( 'TabView', 'functionTabView' );
  $self->application->register_component( 'Table', 'LD_SUBSETS' );
  $self->application->register_component( 'Table', 'LD_ROLES' );
#  $self->application->register_component( 'Info', 'CommentInfo');
#  $self->application->register_component( 'OrganismSelect', 'OSelect');
#  $self->application->register_component( 'Table', 'VarDescTable'  );
  $self->application->register_component( 'Table', 'FunctionalRolesTable'  );

  return 1;
}

sub require_javascript {

  return [ './Html/showfunctionalroles.js' ];

}

##############################################
# Website content is returned by this method #
##############################################
sub output {
  my ( $self ) = @_;

  # needed objects #
  my $application = $self->application();
  $self->{ 'fig' } = $application->data_handle( 'FIG' );
  $self->{ 'cgi' } = $self->application->cgi;
  
  # subsystem name and 'nice name' #
  my $name = $self->{ 'cgi' }->param( 'metasubsystem' );
  my $ssname = $name;

  my $esc_name = uri_escape( $name );

  $ssname =~ s/\_/ /g;

  # look if someone is logged in and can write the subsystem #
  $self->{ 'can_alter' } = 0;
  my $user = $self->application->session->user;

  my $dbmaster = DBMaster->new( -database => 'WebAppBackend' );
  my $ppoapplication = $dbmaster->Backend->init( { name => 'SubsystemEditor' } );
  

  ############################################
  ### GET PREFERENCES FOR AN EXISTING USER ###
  my $preferences = {};

  if ( defined( $user ) && ref( $user ) ) {
    my $pre = $self->application->dbmaster->Preferences->get_objects( { user        => $user,
									application => $ppoapplication } );
    %{ $preferences } = map { $_->name => $_ } @$pre;
  }
  ############################################

  # get a seeduser #
  my $seeduser = '';

  if ( defined( $preferences->{ 'SeedUser' } ) ) {
    $seeduser = $preferences->{ 'SeedUser' }->value;
  }
  if ( $user && $user->has_right( $self->application, 'edit', 'subsystem', $esc_name ) ) {
    $self->{ 'can_alter' } = 1;
    $self->{ 'fig' }->set_user( $seeduser );
    $self->{ 'seeduser' } = $seeduser;
  }

  $self->{ 'metasubsystem' } = new MetaSubsystem( $name, $self->{ 'fig' }, 0 );


  #########
  # TASKS #
  #########

  if ( defined( $self->{ 'cgi' }->param( 'buttonpressed' ) ) && $self->{ 'cgi' }->param( 'buttonpressed' ) eq 'LimitSubsets' ) {

    my @showsets = $self->{ 'cgi' }->param( 'show_set' );
    my @collapsesets = $self->{ 'cgi' }->param( 'collapse_set' );
    my @showrole = $self->{ 'cgi' }->param( 'show_role' );
    
    my $view;

    foreach my $set ( @showsets ) {
      $set =~ /show_set_(.*)/;
      $view->{ 'Subsets' }->{ $1 }->{ 'visible' } = 1;
    }
    foreach my $set ( @collapsesets ) {
      $set =~ /collapse_set_(.*)/;
      $view->{ 'Subsets' }->{ $1 }->{ 'collapsed' } = 1;
    }
    foreach my $role ( @showrole ) {
      $role =~ /show_role_(.*)\##-##(.*)/;
      my $tmprole = $1.'##-##'.$2;
      $view->{ 'Roles' }->{ $tmprole }->{ 'visible' } = 1;
      $view->{ 'Roles' }->{ $tmprole }->{ 'subsystem' } = $2;
    }
    $self->{ 'metasubsystem' }->{ 'view' } = $view;
    $self->{ 'metasubsystem' }->write_metasubsystem();
  }

  $self->get_metass_data();

  ########
  # Data #
  ########

  my ( $frscrlist, $hiddenvalues ) = $self->load_subsystem_spreadsheet( $application, $preferences );

  my $table = $self->application->component( 'SubsystemSpreadsheet' );
  my $frtable = $self->application->component( 'FunctionalRolesTable' );

  ######################
  # Construct the menu #
  ######################

  my $menu = $self->application->menu();

  # Build nice tab menu here
  $menu->add_category( 'Meta Overview', "SubsysEditor.cgi?page=MetaOverview" );

  ##############################
  # Construct the page content #
  ##############################

  # colorpanel #
  my $colorpanel = $self->color_spreadsheet_panel( $preferences, $name );
  # limitdisplaypanel #
  my $limitdisplaypanel = $self->limit_display_panel();
  my $limitsubsetspanel = $self->limit_subsets_panel();

  my $tab_view_component = $self->application->component( 'functionTabView' );
  $tab_view_component->width( 900 );
#  if ( $can_alter ) {
#    $tab_view_component->add_tab( '<H2>&nbsp; Add Genomes to Spreadsheet &nbsp;</H2>', "$addgenomepanel" );
#  }
  $tab_view_component->add_tab( '<H2>&nbsp; Color Spreadsheet &nbsp;</H2>', "$colorpanel" );
  $tab_view_component->add_tab( '<H2>&nbsp; Limit Genomes &nbsp;</H2>', "$limitdisplaypanel" );
  $tab_view_component->add_tab( '<H2>&nbsp; Limit Subsets &nbsp;</H2>', "$limitsubsetspanel" );
  $tab_view_component->add_tab( '<H2>&nbsp; Functional Roles &nbsp;</H2>', $frtable->output() );
#  $tab_view_component->add_tab( '<H2>&nbsp; Show Variants &nbsp;</H2>', "$variantpanel" );

  if ( defined( $self->{ 'cgi' }->param( 'defaulttabhidden' ) ) ) {
    $tab_view_component->default( $self->{ 'cgi' }->param( 'defaulttabhidden' ) );
  }
  else {
    $tab_view_component->default( 0 );
  }

  # add hidden parameter for the tab that is actually open #
  my $dth = 0;
  if ( defined( $self->{ 'cgi' }->param( 'defaulttabhidden' ) ) ) {
    $dth = $self->{ 'cgi' }->param( 'defaulttabhidden' );
  }

  $hiddenvalues->{ 'metasubsystem' } = $name;
  $hiddenvalues->{ 'buttonpressed' } = 'none';
  $hiddenvalues->{ 'defaulttabhidden' } = $dth;

  ###########
  # Content #
  ###########

  my $content = "<H1>Subsystem Metaview for $ssname</H1>";

  # start form #
  $content .= $self->start_form( 'subsys_spreadsheet', $hiddenvalues );
  $content .= "<TABLE><TR><TD>";

  $content .= $tab_view_component->output();
  $content .= "</TD></TR><TR><TD>";
  # put in color legends #
  if ( defined( $self->{ 'legend' } ) ) {
    $content .= $self->{ 'legend' };
    $content .= "</TD></TR><TR><TD>";
  }
  if ( defined( $self->{ 'legendg' } ) ) {
    $content .= $self->{ 'legendg' };
    $content .= "</TD></TR><TR><TD>";
  }
  
#  $content .= "</TD></TR><TR><TD>";

  $content .= $table->output();

  $content .= "</TD></TR>";
  $content .= "</TABLE>";

  # end form 
  $content .= $self->end_form();
  
  return $content;
}

##############################
# draw subsystem spreadsheet #
##############################
sub load_subsystem_spreadsheet {
  my ( $self, $application, $preferences ) = @_;

  # initialize roles, subsets and spreadsheet
  my $roles = $self->{ 'data_roles' };
  my $subsets = $self->{ 'data_subsets' };
  my $spreadsheet_hash = $self->{ 'data_spreadsheethash' };
  my $pegsarr = $self->{ 'data_allpegs' };

  my $user = $application->session->user();
  my $seeduser = $self->{ 'seeduser' };
  my $metass = $self->{ 'metasubsystem' };


  # get a list of sane colors
  my $colors = $self->get_colors();

  #####################################
  # Displaying and Collapsing Subsets #
  #####################################

  # Now - what roles or what subsets do I take?
  my $role_to_group;
  my $columns;
  my $role_to_function;
  my $function_to_role;
  my $toshowroles;
  my %takeroles;
  my %takebutcollapsed;
  my $subsetssupercolumns = 0;

  # here get the roles to show, also the subsets so that we can look them up from the hash
  foreach my $subset ( keys %$subsets ) {

    if ( $metass->{ 'view' }->{ 'Subsets' }->{ $subset }->{ 'visible' } ) {
      if ( $metass->{ 'view' }->{ 'Subsets' }->{ $subset }->{ 'collapsed' } ) {
	$columns->{ $subset } = scalar( keys %$columns );
	$subsetssupercolumns++;
	foreach my $abb ( keys %{ $subsets->{ $subset } } ) {
	  my $fullname = $abb.'##-##'.$subsets->{ $subset }->{ $abb };
	  push @{ $role_to_group->{ $fullname } }, $subset;
	  $takebutcollapsed{ $fullname } = 1;
	}
      }
      else {
	foreach my $abb ( keys %{ $subsets->{ $subset } } ) {
	  my $fullname = $abb.'##-##'.$subsets->{ $subset }->{ $abb };
	  $takeroles{ $fullname } = 1;     
	}
      }
    }
  }

  foreach my $role ( @$roles ) {
    push @$toshowroles, $role;

    my $rolesubsystem = $role->[0].'##-##'.$role->[3];

    $role_to_function->{ $rolesubsystem } = $role->[1];
    $function_to_role->{ $role->[1] } = $role->[2];

    my $th = $metass->{ 'view' }->{ 'Roles' };

    # look if this role is part of a subset
    if ( exists( $role_to_group->{ $role->[0] } ) ) {
      $takeroles{ $rolesubsystem } = 1;
    }
    elsif ( defined( $th->{ $rolesubsystem } && $th->{ $rolesubsystem }->{ 'visible' } ) ) {
      $columns->{ $rolesubsystem } = scalar( keys %$columns );
      $takeroles{ $rolesubsystem } = 1;
    }
    elsif ( $takeroles{ $rolesubsystem } && !defined( $takebutcollapsed{ $rolesubsystem } ) ) {
      $columns->{ $rolesubsystem } = scalar( keys %$columns );
    }
  }

  my $rolelist .= $self->{ 'cgi' }->scrolling_list( -id       => 'rolelist',
						    -name     => 'rolelist',
						    -multiple  => 1,
						    -values   => $toshowroles,
						    -default  => '',
						    -size     => 3
						  );

  ##########################################
  # COLORING SETTINGS OF GENES AND GENOMES #
  ##########################################
  my $peg_to_color_alround;
  my $cluster_colors_alround = {};
  my $genome_colors;
  my $genomes_to_color = {};
  my $columnNameHash;
  my $ind_to_subset;
  my $name = $self->{ 'cgi' }->param( 'metasubsystem' );

  ### COLOR GENES ###
  my $color_by = 'do not color'; #default
  if ( $preferences->{ $name."_color_stuff" } ) {
    $color_by = $preferences->{ $name."_color_stuff" }->value;
  }
  if ( defined( $self->{ 'cgi' }->param( 'color_stuff' ) ) ) {
    $color_by = $self->{ 'cgi' }->param( 'color_stuff' );
    unless ( $preferences->{ $name."_color_stuff" } ) {
      if ( defined( $user ) && ref( $user ) ) {
	$preferences->{ $name."_color_stuff" } = $self->application->dbmaster->Preferences->create( { user        => $user,
												      application => $self->application->backend,
												      name        => $name."_color_stuff",
												      value       => $color_by } );
      }
    }
    else {
      $preferences->{ $name."_color_stuff" }->value( $color_by );
    }
  }
  elsif ( $preferences->{ $name."_color_stuff" } ) {
    $self->{ 'cgi' }->param( 'color_stuff', $preferences->{ $name."_color_stuff" }->value );
  }

  if ( $color_by eq 'by attribute: ' ) {
    my $attr = 'Essential_Gene_Sets_Bacterial';
    
    if ( $preferences->{ $name."_color_by_peg_tag" } ) {
      $attr = $preferences->{ $name."_color_by_peg_tag" }->value;
    }
    if ( defined( $self->{ 'cgi' }->param( 'color_by_peg_tag' ) ) ) {
      $attr = $self->{ 'cgi' }->param( 'color_by_peg_tag' );
      unless ( $preferences->{ $name."_color_by_peg_tag" } ) {
	if ( $user ) {
	  $preferences->{ $name."_color_by_peg_tag" } = $self->application->dbmaster->Preferences->create( { user        => $user,
													     application => $self->application->backend,
													     name        => $name."_color_by_peg_tag",
													     value       => $attr } );
	}
      }
      else {
	$preferences->{ $name."_color_by_peg_tag" }->value( $attr );
      }
    }

    ( $peg_to_color_alround, $cluster_colors_alround ) = $self->get_color_by_attribute_infos( $attr, $pegsarr, $colors );
  }

  ### COLOR GENOMES ###
  my $colorg_by = 'do not color';
  if ( $preferences->{ $name."_colorg_stuff" } ) {
    $colorg_by = $preferences->{ $name."_colorg_stuff" }->value;
  }
  if ( defined( $self->{ 'cgi' }->param( 'colorg_stuff' ) ) ) {
    $colorg_by = $self->{ 'cgi' }->param( 'colorg_stuff' );
    unless ( $preferences->{ $name."_colorg_stuff" } ) {
      if ( $user ) {
	$preferences->{ $name."_colorg_stuff" } = $self->application->dbmaster->Preferences->create( { user        => $user,
												       application => $self->application->backend,
												       name        => $name."_colorg_stuff",
												       value       => $color_by } );
      }
    }
    else {
      $preferences->{ $name."_colorg_stuff" }->value( $colorg_by );
    }
  }
  elsif ( $preferences->{ $name."_colorg_stuff" } ) {
    $self->{ 'cgi' }->param( 'colorg_stuff', $preferences->{ $name."_colorg_stuff" }->value );
  }

  if ( $colorg_by eq 'by attribute: ' ) {
    
    my $attr;
    if ( $preferences->{ $name."_color_by_ga" } ) {
      $attr = $preferences->{ $name."_color_by_ga" }->value;
    }

    if ( defined( $self->{ 'cgi' }->param( 'color_by_ga' ) ) && $self->{ 'cgi' }->param( 'color_by_ga' ) ne '' ) {
      $attr = $self->{ 'cgi' }->param( 'color_by_ga' );

      unless ( $preferences->{ $name."_color_by_ga" } ) {
	if ( $user ) {
	  $preferences->{ $name."_color_by_ga" } = $self->application->dbmaster->Preferences->create( { user        => $user,
														  application => $self->application->backend,
														  name        => $name."_color_by_ga",
														  value       => $attr } );
	}
      }
      elsif ( defined( $attr ) ) {
	$preferences->{ $name."_color_by_ga" }->value( $attr );
	$self->{ 'cgi' }->param( 'color_by_ga', $attr );
      }
      ( $genomes_to_color, $genome_colors ) = $self->get_color_by_attribute_infos_for_genomes( $spreadsheet_hash, $colors );
    }
  }

  ## END OF COLORING SETTINGS ##

  ################################
  # Creating the table from here #
  ################################

  # create table headers
  my $table_columns = [ '', 
			{ name => 'Organism', filter => 1, sortable => 1, width => '150', operand => $self->{ 'cgi' }->param( 'filterOrganism' ) || '' }, 
			{ name => 'Domain', filter => 1, operator => 'combobox', operand => $self->{ 'cgi' }->param( 'filterDomain' ) || '' }, 
			{ name => 'Taxonomy', sortable => 1, visible => 0, show_control => 1 }, 
			{ name => 'Variant', sortable => 1 }
		      ];
    
  my $supercolumns = [ [ '', 1 ], [ '', 1 ], [ '', 1 ], [ '', 1 ] ];
 
  if ( $subsetssupercolumns > 0 ) {
    push @$supercolumns, [ 'Subsets', $subsetssupercolumns ];
  }
  my $supercolstobe;

  my $ii = 4; # this is for keeping in mind in what column we start the Functional Roles

  # if user can write he gets a writable variant column that if first invisible
  if ( $self->{ 'can_alter' } ) {
    push @$table_columns, { name => 'Variant', visible => 0 };
    $ii++;
  }

  my $i = $ii;

  ### Now add the column headers for all functional roles or subsets of the table ###
  foreach my $column ( sort { $columns->{ $a } <=> $columns->{ $b } } keys( %$columns) ) {
    $i++;

    if ( exists( $role_to_function->{ $column } ) ) {
      $column =~ /(.*)\#\#\-\#\#(.*)/;
      my $colrole = $1;
      my $ss_of_role = $2;
      my $tooltip = "<TABLE><TR><TH>Role</TH><TH>Subsystem</TH></TR>\n";
      $tooltip .= "<TR><TD>".$role_to_function->{ $column }."</TD><TD>$ss_of_role</TD></TR</TABLE>";
      push @$supercolstobe, [ $ss_of_role, 1 ];
      push( @$table_columns, { name => $colrole, tooltip => $tooltip });
      $columnNameHash->{ $i } = $colrole.'<BR>'.$tooltip;
      $ind_to_subset->{ $i } = 1;
    }
    else {
      my $tooltip = "<table>";
      foreach my $role ( keys %{ $subsets->{ $column } } ) {
	$tooltip .= "<tr><td>$role</td><td><b>" . $subsets->{ $column }->{ $role } . " </b></td></tr>";
      }
      $tooltip .= "</table>";
      push( @$table_columns, { name => $column, tooltip =>  $tooltip } );
      $columnNameHash->{ $i } = $column.'<BR>'.$tooltip;
    }
  }
  push( @$table_columns, { name => 'Pattern', sortable => 1, visible => 0, show_control => 1 });
  

  # Variants - default is not to show the -1 variants, so we have to ask if that is still true.
  my $show_mo_variants = 0;
  if ( defined( $self->{ 'cgi' }->param( 'buttonpressed' ) ) && $self->{ 'cgi' }->param( 'buttonpressed' ) eq 'MoVariants' || $self->{ 'cgi' }->param( 'showMoVariants' ) ) {
    $show_mo_variants = 1;
  }
  if ( defined( $self->{ 'cgi' }->param( 'buttonpressed' ) ) && $self->{ 'cgi' }->param( 'buttonpressed' ) eq 'HideMoVariants' ) {
    $show_mo_variants = 0;
  }

  # For the lines of the table, walk through spreadsheet hash #
  my $pretty_spreadsheet;
 
  my @sortedrows;

  if ( $preferences->{ 'sort_spreadsheet_by' } && $preferences->{ 'sort_spreadsheet_by' }->value() eq 'alphabetically' ) {
    @sortedrows = sort { $spreadsheet_hash->{ $a }->{ 'name' } cmp $spreadsheet_hash->{ $b }->{ 'name' } } keys %$spreadsheet_hash;
  }
  else {
    @sortedrows = sort { $spreadsheet_hash->{ $a }->{ 'taxonomy' } cmp $spreadsheet_hash->{ $b }->{ 'taxonomy' } } keys %$spreadsheet_hash;
  }

  foreach my $g ( @sortedrows ) {

    my $new_row;
    
    # organism name, domain, taxonomy, variantcode #
    my $gname = $spreadsheet_hash->{ $g }->{ 'name' };
    my $domain = $spreadsheet_hash->{ $g }->{ 'domain' };
    my $tax = $spreadsheet_hash->{ $g }->{ 'taxonomy' };
    my $variant = $spreadsheet_hash->{ $g }->{ 'variant' };

    unless ( $show_mo_variants ) {
      next if ( $variant eq '-1' );
    } 

    # add link to Organism page here #
    $gname = "<A HREF='seedviewer.cgi?page=Organism&organism=" . $g."' target=_blank>$gname</A>";

    my $gentry = $gname;
    if ( defined( $genomes_to_color->{ $g } ) ) {
      $gentry = "<span style='background-color: " . $genome_colors->{ $genomes_to_color->{ $g } } . ";'>$gname</span>";
    }

    my $genome_checkbox = $self->{ 'cgi' }->checkbox( -name     => 'genome_checkbox',
						      -id       => "genome_checkbox_$g",
						      -value    => "genome_checkbox_$g",
						      -label    => '',
						      -checked  => 0,
						      -override => 1,
						    );
    
    push( @$new_row, $genome_checkbox );
    push( @$new_row, $gentry );
    push( @$new_row, $domain );
    push( @$new_row, $tax );
    push( @$new_row, $variant );
    if ( $self->{ 'can_alter' } ) {
      push( @$new_row, "<INPUT TYPE=TEXT NAME=\"variant$g\" SIZE=5 VALUE=\"$variant\">" );
    }

    # now the genes #
    my $thisrow = $spreadsheet_hash->{ $g }->{ 'row' };
    my @row = @$thisrow;

    # memorize all pegs of this row
    my $pegs;
    my $rawpegs;

    # go through data cells and do grouping
    my $data_cells;

    for ( my $i=0; $i<scalar( @row ); $i++ ) {
      push( @$pegs, split( /, /, $row[$i] ) );

      my $roleident = $roles->[$i]->[0].'##-##'.$roles->[$i]->[3];

      next unless ( defined( $takeroles{ $roleident } ) || defined( $takebutcollapsed{ $roleident } ) );

      if ( exists( $role_to_group->{ $roleident } ) ) {
	my $subsetsofthisrole = $role_to_group->{ $roleident };

	my $thiscell = '';
	foreach my $ss ( @$subsetsofthisrole ) {
	  my $index = $columns->{ $ss };
	  unless ( $row[$i] =~ /INPUT/ ) {
	    push( @{ $data_cells->[ $index ] }, split( /, /, $row[$i] ) );
	  }
	}	  
      } 
      else {
	my $index = $columns->{ $roleident };
	push( @{ $data_cells->[ $index ] }, split( /, /, $row[$i] ) );
      }
    }

    foreach my $p ( @$pegs ) {
      if ( $p =~ /(fig\|\d+\.\d+\.peg\.\d+)/ ) {
	push @$rawpegs, $p;
      } 
    }

    my $peg_to_color;
    my $cluster_colors;

    # if we wanna color by cluster put it in here 
    if ( $color_by eq 'by cluster' ) {

      # compute clusters
      my @clusters = $self->{ 'fig' }->compute_clusters( $rawpegs, undef, 5000 );

      for ( my $i = 0; $i < scalar( @clusters ); $i++ ) {

	my %countfunctions = map{ (scalar $self->{ 'fig' }->function_of( $_ ) => 1 ) } @{ $clusters[ $i ] };
	next unless ( scalar( keys %countfunctions ) > 1);

	foreach my $peg ( @{ $clusters[ $i ] } ) {
	  $peg_to_color->{ $peg } = $i;
	}
      }
    }
    elsif ( $color_by eq 'by attribute: ' ) {
      $peg_to_color = $peg_to_color_alround;
      $cluster_colors = $cluster_colors_alround;
    }

    # print actual cells
    my $pattern = "a";
    my $ind = $ii;
    foreach my $data_cell ( @$data_cells ) {
      $ind++;
      my $num_clustered = 0;
      my $num_unclustered = 0;
      my $cluster_num = 0;
      if ( defined( $data_cell ) ) {
	$data_cell = [ sort( @$data_cell ) ];
	my $cell = [];

	foreach my $peg ( @$data_cell ) {
	  
	  if ( $peg =~ /(fig\|\d+\.\d+\.peg\.\d+)/ ) {
	    my $thispeg = $1;
	    my $pegf = $self->{ 'fig' }->function_of( $thispeg );
	    my $pegfnum = '';

	    if ( !defined( $thispeg ) ) {
	      next; 
	    }
	    
	    $thispeg =~ /fig\|\d+\.\d+\.peg\.(\d+)/;
	    my $n = $1;
	    
	    my $peg_link = $self->fid_link( $thispeg );
	    $peg_link = "<A HREF='$peg_link' target=_blank>$n</A>";
	    unless ( $ind_to_subset->{ $ind } ) {
	      my $add_to_peg = $self->get_peg_addition( $pegf );
	      $peg_link .= $add_to_peg;
	    }

	    if ( exists( $peg_to_color->{ $peg } ) ) {
	      unless ( defined( $cluster_colors->{ $peg_to_color->{ $peg } } ) ) {
		$cluster_colors->{ $peg_to_color->{ $peg } } = $colors->[ scalar( keys( %$cluster_colors ) ) ];
	      }
	      $cluster_num = scalar( keys( %$cluster_colors ) );
	      $num_clustered++;
	      push( @$cell, "<span style='background-color: " . $cluster_colors->{ $peg_to_color->{ $peg } } . ";'>$peg_link</span>" );
	    }
	    else {
	      $num_unclustered++;
	      push @$cell, "<span>$peg_link</span>" ;
	    }
	  }
	  else {
	    push @$cell, $peg;
	  }
	}
	my $tt = $columnNameHash->{ $ind };
	push( @$new_row, { data => join( '<br>', @$cell ), tooltip => $tt } );
      }
      else {
	my $tt = $columnNameHash->{ $ind };
	push( @$new_row, { data => '', tooltip => $tt } );
      }
      $pattern .= $num_clustered.$num_unclustered.$cluster_num;
    }

    # pattern
    push(@$new_row, $pattern);

    # push row to table
    push(@$pretty_spreadsheet, $new_row);
  }

  ### create table from parsed data ###
  
  my $table = $application->component( 'SubsystemSpreadsheet' );
  $table->columns( $table_columns );
  $table->data( $pretty_spreadsheet );
  $table->show_top_browse( 1 );
  $table->show_export_button( { strip_html => 1,
				hide_invisible_columns => 1,
			        title      => 'Export plain data to Excel' } );

  my $ss;
  my $ssval = 0;
  foreach my $thisarr ( @$supercolstobe ) {
    if ( !defined( $ss ) ) {
      $ss = $thisarr->[0];
      $ssval++;
    }
    elsif ( $ss eq $thisarr->[0] ) {
      $ssval++;
    }
    else {
      my $nicess = $ss;
      $nicess =~ s/\_/ /g;
      push @$supercolumns, [ $nicess, $ssval ];
      $ss = $thisarr->[0];
      $ssval = 1;
    } 
  }
  if ( defined( $ss ) ) {
      my $nicess = $ss;
      $nicess =~ s/\_/ /g;
      push @$supercolumns, [ $nicess, $ssval ];
  }

  $table->supercolumns( $supercolumns );

  $table->show_select_items_per_page( 1 );

  ### remember some hidden values ###

  my $hiddenvalues = { 'filterOrganism' => '',
		       'sortOrganism'   => '',
		       'filterDomain'   => '',
		       'tableid'        => $table->id,
		       'showMoVariants' => $show_mo_variants };

  # finished
  return ( $rolelist, $hiddenvalues );
}


######################################
# Panel for coloring the spreadsheet #
######################################
sub color_spreadsheet_panel {

  my ( $self, $preferences, $name ) = @_;

  my $content = "<H2>Color genes in spreadsheet</H2>";

  my $default_coloring = $self->{ 'cgi' }->param( 'color_stuff' ) || 'do not color';

  if ( !defined( $self->{ 'cgi' }->param( 'color_by_peg_tag' ) ) && defined( $preferences->{ $name."_color_by_peg_tag" } ) ) {
    $self->{ 'cgi' }->param( 'color_by_peg_tag', $preferences->{ $name."_color_by_peg_tag" }->value );
  }

  my $defaultg_coloring = 'do not color';
  if ( defined( $self->{ 'cgi' }->param( 'colorg_stuff' ) ) ) {
    $defaultg_coloring = $self->{ 'cgi' }->param( 'colorg_stuff' );
  }

  my @color_opt = $self->{ 'cgi' }->radio_group( -name     => 'color_stuff',
				     -values   => [ 'do not color', 'by cluster', 'by attribute: ' ],
				     -default  => $default_coloring,
				     -override => 1
				   );

  my @pegkeys = $self->{ 'fig' }->get_peg_keys();
  push @pegkeys, 'Expert_Annotations';

  #  Compile and order the attribute keys found on pegs:
  my $high_priority = qr/(essential|fitness)/i;
  my @options = sort { $b =~ /$high_priority/o <=> $a =~ /$high_priority/o
		      || uc( $a ) cmp uc( $b )
                    }
    @pegkeys;
  my $blacklist = attribute_blacklist();

  @options = grep { !$blacklist->{ $_ } } @options;
  unshift @options, undef;  # Start list with empty

  my $att_popup = $self->{ 'cgi' }->popup_menu(-name => 'color_by_peg_tag', -values => \@options);

  $content .= join( "<BR>\n", @color_opt );
  $content .= $att_popup;

  $content .= "<H2>Color genomes in spreadsheet</H2>";

  my @goptions = sort { uc( $a ) cmp uc( $b ) } $self->{ 'fig' }->get_genome_keys(); # get all the genome keys
  unshift @goptions, undef; # a blank field at the start

  my @colorg_opt = $self->{ 'cgi' }->radio_group( -name     => 'colorg_stuff',
				      -values   => [ 'do not color', 'by attribute: ' ],
				      -default  => $defaultg_coloring,
				      -override => 1
				    );
  
  my $genome_popup = $self->{ 'cgi' }->popup_menu( -name => 'color_by_ga', -values => \@goptions );
  $content .= join( "<BR>\n", @colorg_opt );
  $content .= $genome_popup;
  if ( $self->{ 'can_alter' } ) {
    $content .= "<BR><BR><INPUT TYPE=BUTTON VALUE='Color Spreadsheet' ONCLICK='SubmitSpreadsheet( \"Color Spreadsheet\", 1 );'>";
  }
  else {
    $content .= "<BR><BR><INPUT TYPE=BUTTON VALUE='Color Spreadsheet' ONCLICK='SubmitSpreadsheet( \"Color Spreadsheet\", 0 );'>";
  }

  return $content;
}

###############
# data method #
###############
sub get_metass_data {

  my ( $self ) = @_;

  my $meta = $self->{ 'metasubsystem' };

  my $subsystems = $meta->{ 'subsystems' };

  my ( $subsets, $spreadsheet, $allpegs );
  my $counter = 0;
  my @roles;  
  my %spreadsheethash;
  my @supercolumns;

  my $frtable = $self->application->component( 'FunctionalRolesTable' );
  $frtable->columns( [ '#', 'Subsystem', 'Abbr.', 'Role Name' ] );
  my $frtablerows;

  my @genomes = keys %{ $meta->{ 'genomes' } };
  my $role_counter = 0;

  foreach my $ssname ( keys %$subsystems ) {
    my $subsystem = $subsystems->{ $ssname };

    $counter ++;
    
    ## get da roles ##
    my @rs = $subsystem->get_roles();
    foreach my $r ( @rs ) { 
      $role_counter++;
      my $abb = $subsystem->get_abbr_for_role( $r );
      my $in = $subsystem->get_role_index( $r );
      push @{ $self->{ 'roles_to_num' }->{ $r } }, [ $role_counter, $abb.'##-##'.$ssname ];
#      $self->{ 'abb_ss_to_num' }->{ $abb.'##-##'.$ssname } = $role_counter;


      push @roles, [ $abb, $r, $in, $ssname ];
      push @$frtablerows, [ $role_counter, $ssname, $abb, $r ];
    }
    
    foreach my $genome ( @genomes ) {
      my $gidx = $subsystem->get_genome_index( $genome );
      
      $spreadsheethash{ $genome }->{ 'name' } = $self->{ 'fig' }->genus_species( $genome );
      $spreadsheethash{ $genome }->{ 'domain' } = $self->{ 'fig' }->genome_domain( $genome );
      $spreadsheethash{ $genome }->{ 'taxonomy' } = $self->{ 'fig' }->taxonomy_of( $genome );

      my $var = $subsystem->get_variant_code( $gidx );
      if ( !defined( $gidx ) ) {
	$var = '-';
      }
      if ( defined( $spreadsheethash{ $genome }->{ 'variant' } ) ) {
	$spreadsheethash{ $genome }->{ 'variant' } .= "_$var";
      }
      else {
	$spreadsheethash{ $genome }->{ 'variant' } = $var;
      }

      my $rowss = $subsystem->get_row( $gidx );
      my @row;
      
      foreach my $tr ( @$rowss ) {
	if ( !defined( $gidx ) ) {
	  push @row, '';
	}
	else {
	  if ( defined( $tr->[0] ) ) {
	    push @$allpegs, @$tr;
	    push @row, join( ', ', @$tr );
	  }
	  else {
	    push @row, '';
	  }
	}
      }
      
      push @{ $spreadsheethash{ $genome }->{ 'row' } }, @row;
    }

    $frtable->data( $frtablerows );
  
  }

  ## now get da subsets ##
  my @subsetArr = keys %{ $meta->{ 'subsets' } };
  
  foreach my $subsetname ( @subsetArr ) {
    next if ( $subsetname eq 'All' );
    my @abb_subsets = keys %{ $meta->{ 'subsets' } };
    
    $subsets->{ $subsetname } = $meta->{ 'subsets' }->{ $subsetname };
  }
  
  $self->{ 'data_roles' } = \@roles;
  $self->{ 'data_subsets' } = $subsets;
  $self->{ 'data_spreadsheethash' } = \%spreadsheethash;
  $self->{ 'data_allpegs' } = $allpegs;

}

######################################
# Panel for coloring the spreadsheet #
######################################
sub limit_display_panel {
  
  my ( $self ) = @_;
  
  # create a new subsystem object #
  my $subsets = $self->{ 'metasubsystem' }->{ 'subsets' };

#  my @tmp = grep { $_ ne "All" } sort $subsystem->get_subset_namesR;
  my $genomes = $self->{ 'metasubsystem' }->{ 'genomes' };
  
  my %options = ( "higher_plants"   => "Higher Plants",
		  "eukaryotic_ps"   => "Photosynthetic Eukaryotes",
		  "nonoxygenic_ps"  => "Anoxygenic Phototrophs",
		  "hundred_hundred" => "Hundred by a hundred",
		  "functional_coupling_paper" => "Functional Coupling Paper",
		  "cyano_or_plant" => "Cyanos OR Plants",
		  "ecoli_essentiality_paper" => "E. coli Essentiality Paper",
		  "has_essentiality_data"	=> "Genomes with essentiality data",
		  "" =>  "All"
		);

  my @options = ( 'All',
		   'NMPDR',
		   'BRC',
		   'Hundred by a hundred' );

  my @genomeListsUser = GenomeLists::getListsForUser();
  unshift @genomeListsUser, 'All';

  my @allsets = keys %$subsets;
#  my @starsets = grep { ( $_ =~ /^\*/ ) } @allsets;
  my @starsets = @allsets;
    
  my $content .= "<P>Limit display of the the genomes in the table based on phylogeny or one of the preselected groups in the left box. Limit display of roles via their subsets and decide which subsets you want to uncollapse in the right box:<P>\n";
  
  # put in table #
  $content .= "<TABLE><TR><TD>";

  # build a little table for the genomes limiting
  $content .= "<H2>&nbsp; Limit displayed Genomes</H2><TABLE><TR><TD>";

  $content .= "<B>Phylogeny</B></TD><TD><B>Specific Sets</B></TD><TD><B>User Sets</B></TD></TR><TR><TD>";

  # phylogeny here #
  $content .= $self->{ 'cgi' }->scrolling_list( -id      => 'phylogeny_set',
				    -name    => 'phylogeny_set',
				    -values  => [ "All", keys %$genomes ],
				    -default => 'All',
				    -size    => 5
				  );
  $content .= "</TD><TD>\n";

  # now special sets #
  $content .= $self->{ 'cgi' }->scrolling_list( -id      => 'special_set', 
				    -name    => 'special_set',
				    -values  => \@options,
				    -default => 'All',
				    -size => 5
				  );
  $content .= "</TD><TD>\n";

  # now special sets #
  $content .= $self->{ 'cgi' }->scrolling_list( -id      => 'user_set', 
				    -name    => 'user_set',
				    -values  => \@genomeListsUser,
				    -default => 'All',
				    -size => 5
				  );
  $content .= "</TD></TR></TABLE>\n";
  $content .= "</TD></TR>\n</TABLE>";

  if ( $self->{ 'can_alter' } ) {
    $content .= "<BR><BR><INPUT TYPE=BUTTON VALUE='Limit Display' ONCLICK='SubmitSpreadsheet( \"LimitDisplay\", 3 );'>";
  }
  else {
    $content .= "<BR><BR><INPUT TYPE=BUTTON VALUE='Limit Display' ONCLICK='SubmitSpreadsheet( \"LimitDisplay\", 2 );'>";
  }

  return $content;
}


######################################
# Panel for coloring the spreadsheet #
######################################
sub limit_subsets_panel {
  
  my ( $self ) = @_;
  
  # create a new subsystem object #
  my $subsets = $self->{ 'metasubsystem' }->{ 'subsets' };

  my @allsets = keys %$subsets;
#  my @starsets = grep { ( $_ =~ /^\*/ ) } @allsets;
  my @starsets = @allsets;

  my @roles = @{ $self->{ 'data_roles' } };
  my %roles;
  foreach my $r ( @roles ) { 
    $roles{ $r->[0].'##-##'.$r->[3] } = $r; 
  }

  my $subsets_table = $self->application->component( 'LD_SUBSETS' );
  my $roles_table = $self->application->component( 'LD_ROLES' );

  $subsets_table->columns( [ 'Name', 'Members', 'Show', 'Collapse' ] );
  $roles_table->columns( [ 'Subsystem', '', '', '', '', '', '', '', '', '' ] );

  my $sstdata = [];
  foreach my $set ( @allsets ) {
    my $show_checked = $self->{ 'metasubsystem' }->{ 'view' }->{ 'Subsets' }->{ $set }->{ 'visible' } || 0;
    my $collapse_checked = $self->{ 'metasubsystem' }->{ 'view' }->{ 'Subsets' }->{ $set }->{ 'collapsed' } || 0;

    my $show_set = $self->{ 'cgi' }->checkbox( -name     => 'show_set',
					       -id       => "show_set_$set",
					       -value    => "show_set_$set",
					       -label    => '',
					       -checked  => $show_checked,
					     );
    my $collapse_set = $self->{ 'cgi' }->checkbox( -name     => 'collapse_set',
						   -id       => "collapse_set_$set",
						   -value    => "collapse_set_$set",
						   -label    => '',
						   -checked  => $collapse_checked,
						 );

    my @mems = keys %{ $subsets->{ $set } };
    foreach ( @mems ) {
      my $rolefullname = $_ . '##-##'. $subsets->{ $set }->{ $_ };
      delete $roles{ $rolefullname };
    }

    my $row = [ $set, { data => join( ', ', @mems ), tooltip => join( ', ', values %{ $subsets->{ $set } } ) },
		$show_set, $collapse_set ];

    push @$sstdata, $row;
  }

  my $rowdata = [];
  my %rowdatahash;
  foreach my $r ( sort keys %roles ) {
    my $checkid = "show_role_$r";

    my $show_checked = 0;
    if ( $self->{ 'metasubsystem' }->{ 'view' }->{ 'Roles' }->{ $r }->{ 'visible' } ) {
      $show_checked = 1;
    }

    my $show_set = $self->{ 'cgi' }->checkbox( -name     => 'show_role',
					       -id       => "$checkid",
					       -value    => "$checkid",
					       -label    => '',
					       -checked  => $show_checked,
					     );
    $r =~ /(.*)##-##.*/;

    $rowdatahash{ $roles{ $r }->[3] }->{ $1 }->{ 'funcrole' } = $roles{ $r }->[1];
    $rowdatahash{ $roles{ $r }->[3] }->{ $1 }->{ 'checkbox' } = $show_set;
  }

  my $isrow = 0;
  foreach my $subsys ( keys %rowdatahash ) {
    my $count = 0;
    my @row = ( $subsys );
    foreach my $abb ( keys %{ $rowdatahash{ $subsys } } ) {
      $count++;
      $isrow = 1;
      push @row, $abb."<BR>".$rowdatahash{ $subsys }->{ $abb }->{ 'checkbox' };
      if ( $count > 8 ) {
	$count = 0;
	push @$rowdata, [ @row ];
	@row = ( $subsys );
      }
    }
    if ( $count > 0 ) {
      for( my $i = $count; $i <= 8; $i++ ) {
	push @row, '';
      }
      push @$rowdata, [ @row ];
    }
  }

  $subsets_table->data( $sstdata );
  $roles_table->data( $rowdata );

  my $content = '<TABLE><TR>';
  $content .= "<TD><B>Subsets</B></TD></TR><TR>";
  $content .= "<TD>Choose which subsets should be visible, and for these if they should be displayed collapsed or show each role in a separate column.";
  $content .= "</TD></TR><TR><TD>";
  $content .= $subsets_table->output();
  if ( $isrow ) {
    $content .= '</TD></TR><TR>';
    $content .= "<TD><B>Functional Roles</B></TD></TR><TR>";
    $content .= "<TD>The following roles are not part of any defined subsystem. Check the roles you want to see in your display.</TD>";
    $content .= '</TR><TR><TD>';
    $content .= $roles_table->output();
  }
  $content .= '</TD></TR></TABLE>';

  if ( $self->{ 'can_alter' } ) {
    $content .= "<BR><BR><INPUT TYPE=BUTTON VALUE='Limit Subsets and Functional Roles' ONCLICK='SubmitSpreadsheet( \"LimitSubsets\", 2 );'>";
  }
  else {
    $content .= "<BR><BR><INPUT TYPE=BUTTON VALUE='Limit Subsets and Functional Roles' ONCLICK='SubmitSpreadsheet( \"LimitSubsets\", 2 );'>";
  }

  return $content;
}


sub fid_link {
    my ( $self, $fid ) = @_;
    my $n;
    my $seeduser = $self->{ 'seeduser' };
    $seeduser = '' if ( !defined( $seeduser ) );

    if ($fid =~ /^fig\|\d+\.\d+\.([a-zA-Z]+)\.(\d+)/) {
      if ( $1 eq "peg" ) {
	  $n = $2;
	}
      else {
	  $n = "$1.$2";
	}
    }

    return "./protein.cgi?prot=$fid&user=$seeduser\&new_framework=0";
}



sub get_color_by_attribute_infos {

  my ( $self, $fig, $attr, $pegsarr, $colors ) = @_; 

  my $scalacolor = is_scala_attribute( $attr );
  my $peg_to_color_alround;
  my $cluster_colors_alround;
  
  if ( defined( $attr ) ) {
    my $groups_for_pegs = get_groups_for_pegs( $fig, $attr, $pegsarr );
    my $i = 0;
    my $biggestitem = 0;
    my $smallestitem = 100000000000;
    
    if ( $scalacolor ) {
      foreach my $item ( keys %$groups_for_pegs ) {
	
	if ( $biggestitem < $item ) {
	  $biggestitem = $item;
	}
	if ( $smallestitem > $item ) {
	  $smallestitem = $item;
	}
      }
      $self->{ 'legend' } = get_scala_legend( $biggestitem, $smallestitem, 'Color legend for CDSs' );
    }
    
    my $leghash;
    foreach my $item ( keys %$groups_for_pegs ) {
      foreach my $peg ( @{ $groups_for_pegs->{ $item } } ) {
	$peg_to_color_alround->{ $peg } = $i;
      }
      
      if ( $scalacolor ) {
	my $col = get_scalar_color( $item, $biggestitem, $smallestitem );
	$cluster_colors_alround->{ $i } = $col;
      }
      else {
	$cluster_colors_alround->{ $i } = $colors->[ scalar( keys( %$cluster_colors_alround ) ) ];
	$leghash->{ $item } = $cluster_colors_alround->{ $i };
      }
      $i++;
    }
    if ( !$scalacolor ) {
      $self->{ 'legend' } = get_value_legend( $leghash, 'Color Legend for CDSs' );
    }
  }
  return ( $peg_to_color_alround, $cluster_colors_alround );
}

sub get_peg_addition {

  my ( $self, $pegf ) = @_;

  my @frs = split( ' / ', $pegf );
  my $pegfnum = '';

  foreach ( @frs ) {
    my $m = $self->{ 'roles_to_num' }->{ $_ };
    next if ( !defined( $m ) );

    foreach my $pm ( @$m ) {
      my $pegfnumtmp = $pm->[0];
      $pegfnum .= '_'.$pegfnumtmp;
    }
  }
  return $pegfnum;
}

sub get_color_by_attribute_infos_for_genomes {
  
  my ( $self, $fig, $cgi, $spreadsheethash, $colors ) = @_; 
  
  my $genomes_to_color;
  my $genome_colors;
  my $leghash;
  my $i = 0;
  my $biggestitem = 0;
  my $smallestitem = 100000000000;
  
  my $attr = $cgi->param( 'color_by_ga' );
  my $scalacolor = is_scala_attribute( $attr );
  
  my @genomes = keys %$spreadsheethash;
  my $groups_for_genomes = get_groups_for_pegs( $fig, $attr, \@genomes );

  if ( $scalacolor ) {
    
    foreach my $item ( keys %$groups_for_genomes ) {
      
      if ( $biggestitem < $item ) {
	$biggestitem = $item;
      }
      if ( $smallestitem > $item ) {
	$smallestitem = $item;
      }
    }
    $self->{ 'legendg' } = get_scala_legend( $biggestitem, $smallestitem, 'Color Legend for Genomes' );
  }
  
  foreach my $item ( keys %$groups_for_genomes ) {
    foreach my $g ( @{ $groups_for_genomes->{ $item } } ) {
      $genomes_to_color->{ $g } = $i;
    }
    
    if ( $scalacolor ) {
      my $col = get_scalar_color( $item, $biggestitem, $smallestitem );
      $genome_colors->{ $i } = $col;
    }
    else {
      $genome_colors->{ $i } = $colors->[ scalar( keys( %$genome_colors ) ) ];
      $leghash->{ $item } = $genome_colors->{ $i };
    } 
    $i++;
  }
  if ( !$scalacolor ) {
    $self->{ 'legendg' } = get_value_legend( $leghash, 'Color Legend for Genomes' );
  }

  return ( $genomes_to_color, $genome_colors );
}


sub get_colors {
  my ( $self ) = @_;

  return [ '#d94242', '#eaec19', '#715ae5', '#25d729', '#f9ae1d', '#19b5b3', '#b519b3', '#ffa6ef',
	   '#744747', '#701414', '#70a444', '#C0C0C0', '#FF40C0', '#FF8040', '#FF0080', '#FFC040', 
	   '#40C0FF', '#40FFC0', '#C08080', '#C0FF00', '#00FF80', '#00C040',
	   "#6B8E23", "#483D8B", "#2E8B57", "#008000", "#006400", "#800000", "#00FF00", "#7FFFD4",
	   "#87CEEB", "#A9A9A9", "#90EE90", "#D2B48C", "#8DBC8F", "#D2691E", "#87CEFA", "#E9967A", 
	   "#FFE4C4", "#FFB6C1", "#E0FFFF", "#FFA07A", "#DB7093", "#9370DB", "#008B8B", "#FFDEAD",
	   "#DA70D6", "#DCDCDC", "#FF00FF", "#6A5ACD", "#00FA9A", "#228B22", "#1E90FF", "#FA8072", 
	   "#CD853F", "#DC143C", "#FF6347", "#98FB98", "#4682B4", "#D3D3D3", "#7B68EE", "#2F4F4F", 
	   "#FF7F50", "#FF69B4", "#BC8F8F", "#A0522D", "#DEB887", "#00DED1", "#6495ED", "#800080", 
	   "#FFD700", "#F5DEB3", "#66CDAA", "#FF4500", "#4B0082", "#CD5C5C", "#EE82EE", "#7CFC00", 
	   "#FFFF00", "#191970", "#FFFFE0", "#DDA0DD", "#00BFFF", "#DAA520", "#008080", "#00FF7F",
	   "#9400D3", "#BA55D3", "#D8BFD8", "#8B4513", "#3CB371", "#00008B", "#5F9EA0", "#4169E1",
	   "#20B2AA", "#8A2BE2", "#ADFF2F", "#556B2F", "#F0FFFF", "#B0E0E6", "#FF1493", "#B8860B",
	   "#FF0000", "#F08080", "#7FFF00", "#8B0000", "#40E0D0", "#0000CD", "#48D1CC", "#8B008B", 
	   "#696969", "#AFEEEE", "#FF8C00", "#EEE8AA", "#A52A2A", "#FFE4B5", "#B0C4DE", "#FAF0E6", 
	   "#9ACD32", "#B22222", "#FAFAD2", "#808080", "#0000FF", "#000080", "#32CD32", "#FFFACD", 
	   "#9932CC", "#FFA500", "#F0E68C", "#E6E6FA", "#F4A460", "#C71585", "#BDB76B", "#00FFFF", 
	   "#FFDAB9", "#ADD8E6", "#778899" ];
}


#####################################################
# List of attributes that are not used for coloring #
#####################################################
sub attribute_blacklist {

  my $list = { 'pfam-domain' => 1,
	       'PFAM'        => 1,
	       'CDD'         => 1 };
  return $list;

}

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3