2 package SGN
::Controller
::Blast
;
8 use Storable qw
| nstore retrieve
|;
9 use List
::Util qw
/sum/;
11 use CXGN
::Tools
::Text qw
/ sanitize_string /;
14 use CXGN
::Blast
::SeqQuery
;
17 BEGIN { extends
'Catalyst::Controller'; }
22 SGN
::Schema
::BlastDb
->dbpath($c->config->{blast_db_path
});
25 sub index :Path
('/tools/blast/') :Args
(0) {
29 my $db_id = $c->req->param('db_id');
31 my $seq = $c->req->param('seq');
32 my $schema = $c->dbic_schema("SGN::Schema");
34 my $blast_db_icons = $c->config->{blast_db_icons
};
35 my $group_rs = $schema->resultset("BlastDbGroup")->search( undef, { order_by
=>'ordinal' });
38 my $dataset_groups = [];
40 my $preselected_database = $c->config->{preselected_blastdb
};
41 my $preselected_category = '';
43 # 224 is the database id for tomato cDNA ITAG 2.40 on production
44 # $preselected_database = 224;
47 my $rs = $schema->resultset("BlastDb")->search( { blast_db_id
=> $db_id }, { join => 'blast_db_group' });
50 $c->throw( is_error
=> 0, message
=> "The blast database with id $db_id could not be found.");
53 $preselected_database = $rs->first()->blast_db_id(); # first database of the category
54 $preselected_category = $rs->first()->blast_db_group_id();
57 foreach my $g ($group_rs->all()) {
58 my @blast_dbs = $g->blast_dbs();
59 push @
$dataset_groups, [ $g->blast_db_group_id, $g->name() ];
63 foreach my $db (@blast_dbs) {
64 push @dbs_AoA, [ $db->blast_db_id(), $db->title(), $db->type() ];
67 my @arr = sort {$a->[1] cmp $b->[1]} @dbs_AoA;
68 $databases->{ $g->blast_db_group_id } = \
@arr;
71 my $cbsq = CXGN
::Blast
::SeqQuery
->new();
72 my @input_options = sort {$a->[0] cmp $b->[0]} ( map { [ $_->name(), $_->name(), $_->type(), $_->example() ] } $cbsq->plugins() );
74 my $cbp = CXGN
::Blast
::Parse
->new();
75 my @parse_options = sort { $b->[0] cmp $a->[0] } ( map { [ $_->name(), $_->name() ] } $cbp->plugins() );
77 # # remove the Basic option from the list (it will still be the default if nothing is selected)
79 # for (my $i=0; $i<@parse_options; $i++) {
80 # if ($parse_options[$i]->[0] eq 'Basic') {
81 # delete($parse_options[$i]);
85 #print STDERR "INPUT OPTIONS: ".Data::Dumper::Dumper(\@input_options);
86 #print STDERR "GROUPS: ".Data::Dumper::Dumper($dataset_groups);
87 #print STDERR "DATASETS: ".Data::Dumper::Dumper($databases);
89 # print STDERR "controller pre-selected db: $preselected_database\n";
91 $c->stash->{input_options
} = \
@input_options;
92 $c->stash->{parse_options
} = \
@parse_options;
93 $c->stash->{preselected_database
} = $preselected_database;
94 $c->stash->{preselected_category
} = $preselected_category;
95 $c->stash->{seq
} = $seq;
96 $c->stash->{preload_id
} = $c->req->param('preload_id');
97 $c->stash->{preload_type
} = $c->req->param('preload_type');
99 $c->stash->{blast_db_icons
} = $blast_db_icons;
101 $c->stash->{databases
} = $databases;
102 $c->stash->{dataset_groups
} = $dataset_groups;
103 $c->stash->{preload_seq
} = $seq;
104 $c->stash->{programs
} = [
105 [ 'blastn', 'blastn (nucleotide to nucleotide db)' ],
106 [ 'blastp', 'blastp (protein to protein db)' ],
107 [ 'blastx', 'blastx (translated nucleotide to protein db)'],
108 [ 'tblastn', 'tblastn (protein to translated nucleotide db)'],
109 [ 'tblastx', 'tblastx (translated nucleotide to translated nucleotide db)'],
111 $c->stash->{template
} = '/tools/blast/index.mas';
114 sub dbinfo
: Path
('/tools/blast/dbinfo') Args
(0) {
120 my $schema = $c->dbic_schema("SGN::Schema");
123 my $cache = $c->config->{basepath
}."/".$c->tempfiles_subdir("blast")."/dbinfo_cache";
124 if ((-e
$cache) && ($c->req->param("force") != 1)) {
125 $data = retrieve
($cache);
128 my $group_rs = $schema->resultset('BlastDbGroup')->search({}, { order_by
=> 'ordinal, name' });
129 while (my $group_row = $group_rs->next()) {
130 my $db_rs = $group_row->blast_dbs->search({ web_interface_visible
=> 't'});
133 while (my $db_row = $db_rs->next()) {
134 my $db = CXGN
::Blast
->new( sgn_schema
=> $c->dbic_schema("SGN::Schema"), blast_db_id
=> $db_row->blast_db_id(), dbpath
=> $c->config->{blast_db_path
});
135 if ($db->files_are_complete()) {
138 title
=> $db->title(),
139 sequence_type
=> $db->type(),
140 sequence_count
=> $db->sequences_count(),
141 update_freq
=> $db->update_freq(),
142 description
=> $db->description(),
143 source_url
=> $db->source_url(),
144 current_as_of
=> strftime
('%m-%d-%y %R GMT',gmtime $db->file_modtime),
145 needs_update
=> $db->needs_update(),
149 push @
$data, [ $group_row->blast_db_group_id(), $group_row->name(), \
@groups ];
152 my $ungrouped_rs = $schema->resultset('BlastDb')->search(
153 { blast_db_group_id
=> undef,
154 web_interface_visible
=> 't' },
155 {order_by
=> 'title'}
158 my @other_groups = ();
160 while (my $db_row = $ungrouped_rs->next()) {
161 my $db = CXGN
::Blast
->new( sgn_schema
=> $c->dbic_schema("SGN::Schema"), blast_db_id
=> $db_row->blast_db_id(), dbpath
=> $c->config->{blast_db_path
});
162 if ($db->files_are_complete()) {
163 push @other_groups, {
164 title
=> $db->title(),
165 sequence_type
=> $db->type(),
166 sequence_count
=> $db->sequences_count(),
167 update_freq
=> $db->update_freq(),
168 description
=> $db->description(),
169 source_url
=> $db->source_url(),
170 current_as_of
=> strftime
('%m-%d-%y %R GMT',gmtime $db->file_modtime),
171 needs_update
=> $db->needs_update(),
175 push @
$data, [ 0, 'Other', \
@other_groups ];
177 nstore
($data, $cache);
180 $c->stash->{template
} = '/tools/blast/dbinfo.mas';
181 $c->stash->{groups
} = $data;
184 sub show_match_seq
: Path
('/tools/blast/match/show') Args
(0) {
187 my $id = $c->req->param('id');
188 my $blast_db_id = $c->req->param('blast_db_id');
189 my $format = $c->req->param('format');
190 my $hilite_coords = $c->req->param('hilite_coords');
194 $id = sanitize_string
( $id );
196 $c->stash->{template
} = '/blast/show_seq/input.mas' unless $blast_db_id && defined $id;
198 # look up our blastdb
199 my $schema = $c->dbic_schema("SGN::Schema");
200 my $bdbo = $schema->resultset("BlastDb")->find($blast_db_id)
201 or $c->throw( is_error
=> 0,
202 message
=> "The blast database with id $blast_db_id could not be found (please set the blast_db_id parameter).");
203 my $seq = $bdbo->get_sequence($id) # returns a Bio::Seq object.
204 or $c->throw( is_error
=> 0,
205 message
=> "The sequence could not be found in the blast database with id $blast_db_id.");
207 # parse the coords param
210 my ($s, $e) = split "-", $_;
211 defined $_ or die 'parse error' for $s, $e;
215 split ',', ( $hilite_coords || '' );
217 # dispatch to the proper view
218 if ($format eq 'html') {
221 my $download_link = ''; #do { $format => 'fasta_file'; '?'.$c->req->body };
223 $c->stash->{template
} = '/blast/show_seq/html.mas';
224 $c->stash->{seq
} = $seq;
225 $c->stash->{highlight_coords
} = \
@coords;
226 $c->stash->{source
} = '"'.$bdbo->title().'" BLAST dataset ';
227 $c->stash->{format_links
} = [
228 ( $seq->length > 500_000 ?
() : [ 'View as FASTA' => $view_link ] ),
229 [ 'Download as FASTA' => $download_link ],
231 $c->stash->{blast_url
} = '/tools/blast';
234 elsif($format eq 'fasta_file' || $format eq 'fasta_text') {
237 my $attachment = $format eq 'fasta_file' ?
'attachment;' : '';
238 $c->res->body(qq | Content
-Type
: text
/plain
\n\n | .
240 "Content-Disposition: $attachment filename=$id.fa\n\n".
241 Bio
::SeqIO
->new( -fh
=> \
*STDOUT
, -format
=> 'fasta' )
242 ->write_seq( $seq ));
246 sub blast_help
:Path
('/help/tools/blast') :Args
(0) {
250 $c->stash->{template
} = '/help/blast.mas';