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

View of /FigWebServices/SimBlockDisplay.cgi

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (download) (annotate)
Thu Jun 9 05:53:14 2005 UTC (14 years, 6 months ago) by parrello
Branch: MAIN
CVS Tags: merge-trunktag-bobdev_news-2, Root-bobdev_news, merge-bobdev_news-1, merge-trunktag-bobdev_news-1, merge-bodev_news-3, caBIG-00-00-00, merge-bobdev_news-2, merge-trunktag-bodev_news-3
Branch point for: Branch-bobdev_news
Changes since 1.1: +113 -10 lines
*** empty log message ***

#!/usr/bin/perl -w

BEGIN {
    # 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.

For debugging purposes, you can specify the B<Trace> parameter to
set the tracing level. You can also set the B<ShowMode> parameter to
C<1> to display a table of the parameters passed by the form. So,
for example,

C<< http://myseedurl/CGI/SimBlockDisplay.cgi?ShowMode=1 >>

will set the form action to display the form contents without processing
them, while

C<< http://myseedurl/CGI/SimBlockDisplay.cgi?Trace=3 >>

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,

C<< http://myseedurl/CGI/SimBlockDisplay.cgi?Trace=3%20SimBlocks%20DBObject >>

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

=cut

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

# Get the CGI parameters.
my $query = new CGI;
my $traceLevel = $query->param("Trace");
if (!defined $traceLevel || length $traceLevel == 0) {
    $traceLevel = 0;
}
TSetup("$traceLevel Tracer", "QUEUE");
# Choose the output script based on the ShowMode parameter.
my $script = ($query->param('ShowMode') ? 'FormDisplay' : 'SimBlockPattern');
# Decide whether or not we need debugging fields.
my $traceFields = (Tracer::DebugMode() ? Tracer::GetFile("Html/DebugFragment.html") : "");
# Create the variable hash used to generate the web page. We start with the debug-related
# fields we've already computed.
my %varHash = ( script => $script, DebugData => $traceFields );
# 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},
                                                                           $sets{set1});
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} },
                                         "Html");
}
# 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;
Trace("Building web page.") if T(1);
# Flush the trace messages.
$varHash{TraceMessages} = QTrace('html');
# Generate the web page.
my $page = PageBuilder::Build("<Html/SimBlockDisplay.html", \%varHash, "Html");
print $page;

1;

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3