use CXGN::Blast object instead of outdated CXGN::BlastDb object.
[sgn.git] / lib / SGN / Controller / Blast.pm
bloba8781e5d8a8c17051d1fb66b0e1417f5213aebb6
2 package SGN::Controller::Blast;
4 use Moose;
6 use POSIX;
7 use Data::Dumper;
8 use Storable qw | nstore retrieve |;
9 use List::Util qw/sum/;
10 use Bio::SeqIO;
11 use CXGN::Tools::Text qw/ sanitize_string /;
12 #use SGN::Schema;
13 use CXGN::Blast;
14 use CXGN::Blast::SeqQuery;
17 BEGIN { extends 'Catalyst::Controller'; }
19 sub AUTO {
20 my $self = shift;
21 my $c = shift;
22 SGN::Schema::BlastDb->dbpath($c->config->{blast_db_path});
25 sub index :Path('/tools/blast/') :Args(0) {
26 my $self = shift;
27 my $c = shift;
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' });
37 my $databases = {};
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;
46 if ($db_id) {
47 my $rs = $schema->resultset("BlastDb")->search( { blast_db_id => $db_id }, { join => 'blast_db_group' });
49 if ($rs == 0) {
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() ];
61 my @dbs_AoA;
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)
78 # #
79 # for (my $i=0; $i<@parse_options; $i++) {
80 # if ($parse_options[$i]->[0] eq 'Basic') {
81 # delete($parse_options[$i]);
82 # }
83 # }
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) {
115 my $self = shift;
116 my $c = shift;
118 my $data = [];
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);
127 else {
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'});
131 my @groups = ();
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()) {
137 push @groups, {
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 = ();
159 if ($ungrouped_rs) {
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) {
185 my $self = shift;
186 my $c = shift;
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');
192 $format ||= 'html';
193 $blast_db_id += 0;
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 $bo = CXGN::Blast->new( {
204 sgn_schema => $schema,
205 blast_db_id => $blast_db_id,
206 dbpath => $c->config->{blast_db_path}
209 print STDERR "Path:". $c->config->{blast_db_path}." db_id: ".$blast_db_id."\n";
211 my $seq = $bo->get_sequence($id) # returns a Bio::Seq object.
212 or $c->throw( is_error => 0,
213 message => "The sequence could not be found in the blast database with id $blast_db_id.");
215 # parse the coords param
216 my @coords =
217 map {
218 my ($s, $e) = split "-", $_;
219 defined $_ or die 'parse error' for $s, $e;
220 [ $s, $e ]
222 grep length,
223 split ',', ( $hilite_coords || '' );
225 # dispatch to the proper view
226 if ($format eq 'html') {
228 my $view_link = '';
229 my $download_link = ''; #do { $format => 'fasta_file'; '?'.$c->req->body };
231 $c->stash->{template} = '/blast/show_seq/html.mas';
232 $c->stash->{seq} = $seq;
233 $c->stash->{highlight_coords} = \@coords;
234 $c->stash->{source} = '"'.$bo->title().'" BLAST dataset ';
235 $c->stash->{format_links} = [
236 ( $seq->length > 500_000 ? () : [ 'View as FASTA' => $view_link ] ),
237 [ 'Download as FASTA' => $download_link ],
239 $c->stash->{blast_url} = '/tools/blast';
242 elsif($format eq 'fasta_file' || $format eq 'fasta_text') {
245 my $attachment = $format eq 'fasta_file' ? 'attachment;' : '';
246 $c->res->body(qq | Content-Type: text/plain\n\n | .
248 "Content-Disposition: $attachment filename=$id.fa\n\n".
249 Bio::SeqIO->new( -fh => \*STDOUT, -format => 'fasta' )
250 ->write_seq( $seq ));
254 sub blast_help :Path('/help/tools/blast') :Args(0) {
255 my $self = shift;
256 my $c = shift;
258 $c->stash->{template} = '/help/blast.mas';