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

View of /FigWebServices/SimBlockDisplay.cgi

Parent Directory Parent Directory | Revision Log Revision Log

Revision 1.7 - (download) (annotate)
Tue Apr 29 08:18:30 2008 UTC (11 years, 9 months ago) by parrello
Branch: MAIN
CVS Tags: mgrast_dev_08112011, rast_rel_2009_05_18, mgrast_dev_08022011, rast_rel_2014_0912, rast_rel_2008_06_18, myrast_rel40, rast_rel_2008_06_16, mgrast_dev_05262011, rast_rel_2008_12_18, mgrast_dev_04082011, rast_rel_2008_07_21, rast_rel_2010_0928, rast_2008_0924, mgrast_version_3_2, mgrast_dev_12152011, mgrast_dev_06072011, rast_rel_2008_09_30, rast_rel_2009_0925, rast_rel_2010_0526, rast_rel_2014_0729, mgrast_dev_02212011, rast_rel_2010_1206, mgrast_release_3_0, mgrast_dev_03252011, rast_rel_2010_0118, mgrast_rel_2008_0924, mgrast_rel_2008_1110_v2, rast_rel_2009_02_05, rast_rel_2011_0119, mgrast_rel_2008_0625, mgrast_release_3_0_4, mgrast_release_3_0_2, mgrast_release_3_0_3, mgrast_release_3_0_1, mgrast_dev_03312011, mgrast_release_3_1_2, mgrast_release_3_1_1, mgrast_release_3_1_0, mgrast_dev_04132011, rast_rel_2008_10_09, mgrast_dev_04012011, rast_release_2008_09_29, mgrast_rel_2008_0806, mgrast_rel_2008_0923, mgrast_rel_2008_0919, rast_rel_2009_07_09, rast_rel_2010_0827, mgrast_rel_2008_1110, myrast_33, rast_rel_2011_0928, rast_rel_2008_09_29, mgrast_rel_2008_0917, rast_rel_2008_10_29, mgrast_dev_04052011, mgrast_dev_02222011, rast_rel_2009_03_26, mgrast_dev_10262011, rast_rel_2008_11_24, rast_rel_2008_08_07, HEAD
Changes since 1.6: +2 -2 lines
Fixed. Deprecated ScriptSetup methods are no longer exported by Tracer.

#!/usr/bin/perl -w
# Copyright (c) 2003-2006 University of Chicago and Fellowship
# for Interpretations of Genomes. All Rights Reserved.
# This file is part of the SEED Toolkit.
# The SEED Toolkit is free software. You can redistribute
# it and/or modify it under the terms of the SEED Toolkit
# Public License.
# You should have received a copy of the SEED Toolkit Public License
# along with this program; if not write to the University of Chicago
# at info@ci.uchicago.edu or the Fellowship for Interpretation of
# Genomes at veronika@thefig.info or download a copy from
# http://www.theseed.org/LICENSE.TXT.

    # Print the HTML header.
    print "CONTENT-TYPE: text/html\n\n";

=head1 Similarity Block Display

This script processes input from the C<SimBlockForm.cgi> script's web page and
produces lists of which genomes are in set 1 or set 2 and which blocks are in
set 1, set 2, or both genome sets. The user can select a particular block in
one of the columns and click the appropriate button to generate an alignment
display in the embedded frame below the block lists.

Common blocks will be displayed in red if they have snip differences. A I<snip
difference> is a column in which the contents for set 0 are different from the
contents for set 1. So, for example, if column 6 is always A or G for set 0 and
always T for set 1, there is a snip difference. The snip difference is therefore
a much stronger condition than merely having different values in a column. If
column 6 contained A and G in set 0 and only A in set 1, it would not be a snip
difference, because A occurs in both sets.

When a block is selected for display in the lower part of the form, the snip
differences are shown in a table. Therefore, that table will be empty unless
the block name is displayed in red.

At the bottom of the page, an alignment of the snips in the common blocks
is displayed. If this alignment is sufficiently large, it will not show up
properly in Firefox.

For debugging purposes, you can specify the B<Trace> parameter to
set the tracing level. So, for example,


runs the standard processing script at a trace level of 3. Normally, only the
script itself and B<Tracer> tracing is active; however, you can activate other tracing modules
by appending them to the trace level. Thus,


activates tracing for the similarity block module (C<SimBlocks.pm>) and the data
base object (C<ERDBObject.pm>).


use strict;
use CGI;
use Tracer;
use PageBuilder;
use SimBlocks;

# Get the CGI parameters.
my ($query, $varHash) = Tracer::ScriptSetup();
# Do this next part safely.
eval {
    # Next we get the list of genomes in each set. These come from the radio
    # buttons on the incoming form. Basically, we look for any option whose value
    # is "set0" or "set1", and put it in the appropriate list. To make this process
    # simpler, we set up a hash to contain the results.
    my %sets = ( set0 => [], set1 => [] );
    my @params = $query->param;
    for my $param (@params) {
        my $parmValue = $query->param($param);
        if (exists $sets{$parmValue}) {
            push @{$sets{$parmValue}}, "$param";
    # Set up the attribute for the blocks with snip differences.
    my $snipAttribute = { class => 'snippy' };
    # The genome IDs are converted to list options in the upper list boxes.
    for my $setID (keys %sets) {
        # Get the list of values for this set.
        my $valueList = $sets{$setID};
        # Get its length.
        my $valueCount = @{$valueList};
        # Make sure the length is at least 2. Otherwise, the scrolling list becomes a
        # combo box.
        if ($valueCount < 2) {
            $valueCount = 2;
        # Build a multi-selection scrolling list big enough to show all the genome IDs. Note
        # that we pre-select every element.
        $varHash->{"${setID}GenomeIDs"} = $query->scrolling_list("${setID}Genomes", $valueList,
                                                               $valueList, $valueCount, 1);
    # Now we create the similarity block object.
    my $simBlocks = SimBlocks->new();
    Trace("Comparing genome sets.") if T(1);
    # Get a comparison of the genome sets.
    my %blocks;
    ($blocks{set0}, $blocks{set1}, $blocks{both}) = $simBlocks->CompareGenomes($sets{set0},
    Trace("Formatting lists.") if T(1);
    # Use the results to generate the scrolling lists for the similarity blocks. Our approach
    # here is very much like what we did earlier for the genome IDs, but we put a maximum of
    # 50 on the display size of each list.
    for my $setID (keys %blocks) {
        # Get the list of blocks for this set.
        my $valueHash = $blocks{$setID};
        my @valueList = sort keys %{$valueHash};
        # Compute the number of blocks.
        my $valueCount = @valueList;
        $varHash->{"${setID}Count"} = $valueCount;
        # Constrain it to compute the list height.
        if ($valueCount > 50) {
            $valueCount = 50;
        } elsif ($valueCount < 2) {
            $valueCount = 2;
        # Create a hash to map block IDs to their descriptive names.
        my %labelMap = ();
        # Create a hash for the list box attributes. This hash will be empty for
        # everything but the both-list.
        my %attributes = ();
        # Loop through the blocks, counting snip differences and associating labels.
        my $snipCount = 0;
        for my $blockID (@valueList) {
            # If this is the both-list, we need to count the snip differences.
            if ($setID eq "both") {
                # Get the snip differences.
                my %snipHash = $simBlocks->SnipScan($blockID, $sets{set0}, $sets{set1});
                my $snipDelta = (keys %snipHash);
                # If snip differences were found, we need to record the fact.
                if ($snipDelta > 0) {
                    # Count the new snips.
                    $snipCount += $snipDelta;
                    # Highlight the block.
                    $attributes{$blockID} = $snipAttribute;
            # Regardless of which list it is, we need to store the label.
            ($labelMap{$blockID}) = $valueHash->{$blockID}->Value('GroupBlock(description)');
        # If this is the both-list, save the snip count.
        if ($setID eq "both") {
            $varHash->{snipCount} = $snipCount;
        # Build a single-selection scrolling list for this set of blocks.
        $varHash->{"${setID}BlockIDs"} =
            $query->scrolling_list(-name => "${setID}Blocks",
                                   -values => \@valueList,
                                   -size => $valueCount,
                                   -labels => \%labelMap,
                                   -attributes => \%attributes);
    # Now we need to build the alignment. First, we read the alignment table row fragment.
    Trace("Building alignment.") if T(1);
    my $alignmentRow = Tracer::GetFile("Html/AlignmentRow.html");
    # Next, we need to create an alignment hash from the similarities.
    my @genomes = sort @{$sets{set1}}, @{$sets{set0}};
    my @blocks = (keys %{$blocks{both}});
    my %alignment = $simBlocks->GetAlignment(\@blocks, \@genomes);
    # Loop through the alignment, building the rows.
    my $alignmentHTML = "";
    for my $genome (@genomes) {
        # Get this genome's set number.
        my $setNumber = SimBlocks::SetNumber($genome, $sets{set0}, $sets{set1});
        # Produce the alignment row.
        $alignmentHTML .= PageBuilder::Build($alignmentRow, { genomeID => $genome,
                                                              setNumber => $setNumber,
                                                              dna => $alignment{$genome} },
    # Put the alignment in the variable hash.
    $varHash->{alignment} = $alignmentHTML;
    # Now we need to create the distance matrix.
    Trace("Computing distances.") if T(1);
    my %distanceMatrix = SimBlocks::DistanceMatrix(\%alignment);
    # Get the maximum distance.
    my $max = 0;
    for my $dist (values %distanceMatrix) {
        if ($dist > $max) {
            $max = $dist;
    # Clean up the formatting of the distances.
    for my $distanceKey (keys %distanceMatrix) {
        my $distance = $distanceMatrix{$distanceKey};
        # Compute the color of the distance.
        my $intensity = int(($max - $distance) * 200 / $max) + 55;
        my $color = sprintf("%02X", $intensity);
        $color = "#$color$color" . "FF";
        my $distanceString;
        if ($distance == 0) {
            $distanceString = "0.00000";
        } elsif ($distance == 1) {
            $distanceString = "1.00000";
        } elsif ($distance >= 0.00001) {
            $distanceString = sprintf("%.5f", $distance);
            $distanceString .= "0" x (7 - length $distanceString);
        } else {
            $distanceString = sprintf("%E", $distance);
        $distanceMatrix{$distanceKey} =
            "<td align=\"right\" bgcolor=\"$color\">$distanceString</td>";;
    # Format it into a table.
    my $thString = "<th align=\"center\" scope=\"col\">";
    my $tdString = "<td align=\"right\">";
    my $distanceHTML = "<tr><td>&nbsp;</td>$thString" .
        join("</th><th align=\"center\">", @genomes) . "</th></tr>\n";
    for my $genome1 (@genomes) {
        my $row = "<tr><th scope=\"row\">$genome1</th>";
        $row .= join("", map { $distanceMatrix{"$genome1/$_"} } @genomes);
        $row .= "</tr>\n";
        $distanceHTML .= $row;
    # Add it to the variable hash.
    $varHash->{distanceMatrix} = $distanceHTML;
# Check for an error from the EVAL.
if ($@) {
    Trace("Script error: $@") if T(0);
# Display the web page.
Tracer::ScriptFinish("Html/SimBlockDisplay.html", $varHash);


MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3