--- 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