--- SearchHelper.pm 2007/05/17 23:43:30 1.32
+++ SearchHelper.pm 2007/06/19 21:28:21 1.33
@@ -19,6 +19,7 @@
use FeatureQuery;
use URI::Escape;
use PageBuilder;
+ use POSIX;
=head1 Search Helper Base Class
@@ -875,7 +876,7 @@
=head3 OrganismData
-C<< my ($orgName, $group) = $shelp->Organism($genomeID); >>
+C<< my ($orgName, $group, $domain) = $shelp->Organism($genomeID); >>
Return the name and status of the organism corresponding to the specified genome ID.
For performance reasons, this information is cached in a special hash table, so we
@@ -1097,7 +1098,7 @@
$fastaLabel = $fid;
}
# Now proceed according to the sequence type.
- if ($desiredType eq 'prot') {
+ if ($desiredType =~ /prot/) {
# We want protein, so get the translation.
$fastaData = $sprout->FeatureTranslation($figID);
Trace(length $fastaData . " characters returned for translation of $fastaLabel.") if T(3);
@@ -1166,13 +1167,18 @@
Trace("FASTA data sequence: $fastaData") if T(4);
# Only proceed if no error was detected.
if ($okFlag) {
- # We need to format the sequence into 60-byte chunks. We use the infamous
- # grep-split trick. The split, because of the presence of the parentheses,
- # includes the matched delimiters in the output list. The grep strips out
- # the empty list items that appear between the so-called delimiters, since
- # the delimiters are what we want.
- my @chunks = grep { $_ } split /(.{1,60})/, $fastaData;
- $retVal = join("\n", ">$fastaLabel", @chunks, "");
+ if ($desiredType =~ /pattern/i) {
+ # We're doing a scan, so only the data is passed in.
+ $retVal = $fastaData;
+ } else {
+ # We need to format the sequence into 60-byte chunks. We use the infamous
+ # grep-split trick. The split, because of the presence of the parentheses,
+ # includes the matched delimiters in the output list. The grep strips out
+ # the empty list items that appear between the so-called delimiters, since
+ # the delimiters are what we want.
+ my @chunks = grep { $_ } split /(.{1,60})/, $fastaData;
+ $retVal = join("\n", ">$fastaLabel", @chunks, "");
+ }
}
# Return the result.
return $retVal;
@@ -2774,6 +2780,79 @@
$dockString);
}
}
+ } elsif ($type eq 'role') {
+ # Here the caller wants a functional role assignment. The key is the feature ID.
+ $retVal = $sprout->FunctionOf($text);
+ } elsif ($type eq 'loc') {
+ # This is a tough one. We need to find the nearest feature in the appropriate direction
+ # on the contig, and then output its id, functional role, and link button.
+ if ($text =~ /^(.)\/(.+)/) {
+ my ($direction, $locString) = ($1, $2);
+ Trace("Location request of type $direction for $locString.") if T(3);
+ # Convert the location string into a location object.
+ my $loc = BasicLocation->new($locString);
+ # Get the contig ID.
+ my $contigID = $loc->Contig;
+ # Compute the contig length.
+ my $contigLen = $sprout->ContigLength($contigID);
+ # Widen by the area to search in both directions.
+ $loc->Widen(5000);
+ # Now, if we're doing a before (-) search, we set the end point to the area's mid point.
+ # If we're doing an after (+) search, we set the begin point to the area's mid point.
+ my $mid = ($loc->Left + $loc->Right) / 2;
+ # Compute the search direction.
+ my $searchDir = ($direction eq $loc->Dir ? 1 : -1);
+ # Adjust the midpoint so that it is different in the before direction from what it would
+ # be in the after direction.
+ if ($mid != int($mid)) {
+ # Here we need to round. The thing here is we want to round in a way that separates
+ # the after-search choice from the before-search choice.
+ if ($direction eq $loc->Dir) {
+ $mid = ceil($mid);
+ } else {
+ $mid = floor($mid);
+ }
+ } elsif ($direction eq '+') {
+ # Here the midpoint is on a nucleotide and we are doing the after search. We bump the
+ # midpoint toward the end point.
+ $mid += $loc->NumDirection;
+ }
+ # Now put the midpoint on the proper end of the region.
+ if ($direction eq '+') {
+ $loc->SetBegin($mid);
+ } else {
+ $loc->SetEnd($mid);
+ }
+ Trace("Search region is " . $loc->String . ".") if T(3);
+ # Find all the genes in the region.
+ my ($fidList, $beg, $end) = $sprout->GenesInRegion($loc->Contig, $loc->Left, $loc->Right);
+ Trace(scalar(@{$fidList}) . " features found.") if T(3);
+ # Look for the best match.
+ my $distance = 5000;
+ my $chosenFid = undef;
+ for my $fid (@{$fidList}) {
+ # Get the feature's location.
+ my ($locString) = $sprout->FeatureLocation($fid);
+ my $locObject = BasicLocation->new($locString);
+ # Check its begin point to see if we should keep it.
+ my $newDistance = ($mid - $locObject->Begin) * $searchDir;
+ Trace("Distance from $mid to $locString is $newDistance.") if T(4);
+ if ($newDistance > 0 && $newDistance < $distance) {
+ $distance = $newDistance;
+ $chosenFid = $fid;
+ }
+ }
+ # Only proceed if we found something.
+ if (defined $chosenFid) {
+ my $role = $sprout->FunctionOf($chosenFid);
+ my $linkButton = SearchHelper::FakeButton('NMPDR', "protein.cgi", undef,
+ prot => $chosenFid, SPROUT => 1,
+ new_framework => 0, user => '');
+ $retVal = "$chosenFid $linkButton $role";
+ }
+ } else {
+ Confess("Invalid location request %%loc=$text.");
+ }
}
# Return the result.
return $retVal;
@@ -2947,7 +3026,7 @@
# Compute the target-frame HTML.
my $targetHtml = ($target ? " target=\"$target\"" : "");
# Assemble the result.
- return "$caption
";
+ return "$caption";
}
=head3 Formlet