1 package SGN
::Controller
::Locus
;
5 SGN::Controller::Locus - Catalyst controller for the locus page
6 (replacing the old cgi script)
11 use namespace
::autoclean
;
13 use URI
::FromHash
'uri';
15 use CXGN
::Phenome
::Locus
;
16 use CXGN
::Phenome
::Schema
;
17 use CXGN
::Tools
::Organism
;
18 use CXGN
::Phenome
::Locus
::LinkageGroup
;
20 BEGIN { extends
'Catalyst::Controller' }
21 with
'Catalyst::Component::ApplicationAttribute';
26 isa
=> 'DBIx::Class::Schema',
32 sub locus_search
: Path
('/search/locus') Args
(0) {
35 my ($organism_names_ref, $organism_ids_ref)=CXGN
::Tools
::Organism
::get_existing_organisms
( $c->dbc->dbh);
37 unshift @
$organism_names_ref, '';
38 unshift @
$organism_ids_ref, '';
41 for my $id ( @
$organism_ids_ref ) {
42 push( @organism_ref, [$id, $organism_names_ref->[$index]] );
45 my $lg_names_ref = CXGN
::Phenome
::Locus
::LinkageGroup
::get_all_lgs
( $c->dbc->dbh );
47 template
=> '/search/loci.mas',
48 organism_ref
=> \
@organism_ref,
49 lg_names_ref
=> $lg_names_ref,
56 shift->_app->dbic_schema( 'CXGN::Phenome::Schema' )
62 Public path: /locus/0/new
66 Chained off of L</get_locus> below.
70 sub new_locus
: Chained
('get_locus') PathPart
('new') Args
(0) {
71 my ( $self, $c ) = @_;
73 template
=> '/locus/index.mas',
78 locus
=> $c->stash->{locus
},
79 schema
=> $self->schema,
85 sub view_by_name
: Path
('/locus/view/') Args
(0) {
89 my $symbol = $c->req->param("symbol");
90 my $locusname = $c->req->param("locus");
91 my $species = $c->req->param("species");
95 if ($symbol && $species) {
96 $locus = $c->stash->{locus
} = CXGN
::Phenome
::Locus
->new_with_symbol_and_species($c->dbc->dbh, $symbol, $species);
100 $locus = $c->stash->{locus
} = CXGN
::Phenome
::Locus
->new_with_locusname($c->dbc->dbh, $locusname);
103 if (defined($locus) && defined($locus->get_locus_id())) {
104 $locus_id = $locus->get_locus_id();
105 my $url = "/locus/$locus_id/view";
106 $c->res->redirect($url, 301);
109 $c->stash->{template
} = 'generic_message.mas';
110 $c->stash->{message
} = "No locus was found for the identifier provided ($symbol $locusname $species).";
111 # forward to search page ?
120 Public path: /locus/<locus_id>/view
122 View a locus detail page.
124 Chained off of L</get_locus> below.
128 sub view_locus
: Chained
('get_locus') PathPart
('view') Args
(0) {
129 my ( $self, $c, $action) = @_;
130 my $locus = $c->stash->{locus
};
132 $c->forward('get_locus_extended_info');
135 my $logged_user = $c->user;
136 my $person_id = $logged_user->get_object->get_sp_person_id if $logged_user;
137 my $curator = $logged_user->check_roles('curator') if $logged_user;
138 my $submitter = $logged_user->check_roles('submitter') if $logged_user;
139 my $sequencer = $logged_user->check_roles('sequencer') if $logged_user;
140 my $dbh = $c->dbc->dbh;
142 my $trait_db_name => $c->get_conf('trait_ontology_db_name');
145 ###Check if a locus page can be printed###
146 my $locus_id = $locus ?
$locus->get_locus_id : undef ;
148 print STDERR
"LOCUS_ID: $locus_id ACTION: $action\n\n";
150 # print message if locus_id is not valid
151 unless ( ( $locus_id =~ m
/^\d+$/ ) || ($action eq 'new' && !$locus_id) ) {
152 $c->throw_404( "No locus exists for that identifier." );
154 unless ( $locus || !$locus_id && $action && $action eq 'new' ) {
155 $c->throw_404( "No locus exists for that identifier." );
158 # print message if the locus is obsolete
159 my $obsolete = $locus->get_obsolete();
160 if ( $obsolete eq 't' && !$curator ) {
161 $c->throw(is_client_error
=> 0,
162 title
=> 'Obsolete locus',
163 message
=> "Locus $locus_id is obsolete!",
164 developer_message
=> 'only curators can see obsolete loci',
165 notify
=> 0, #< does not send an error email
170 # print message if locus_id does not exist
171 if ( !$locus && $action ne 'new' && $action ne 'store' ) {
172 $c->throw_404('No locus exists for this identifier');
177 my $owner_ids = $c->stash->{owner_ids
} || [] ;
178 if ( $locus && ($curator || $person_id && ( grep /^$person_id$/, @
$owner_ids ) ) ) {
181 my $dbxrefs = $self->locus_dbxrefs_by_db( $c );
182 my $pubs = $self->_locus_pubs( $c);
183 my $image_ids = $locus->get_figure_ids;
184 my $cview_tmp_dir = $c->tempfiles_subdir('cview');
188 # 4. look up xrefs for all of them
189 map $c->feature_xrefs( $_, { exclude
=> 'locuspages' } ),
190 # 3. plus primary locus name
191 $locus->get_locus_name,
192 # 2. list of locus alias strings
193 map $_->get_locus_alias,
194 # 1. list of locus alias objects
195 $locus->get_locus_aliases( 'f', 'f' );
197 my ($feature, $src_feature) = $locus->get_src_feature;
200 template
=> '/locus/index.mas',
203 locus_id
=> $locus_id ,
205 submitter
=> $submitter,
206 sequencer
=> $sequencer,
207 person_id
=> $person_id,
208 user
=> $logged_user,
211 is_owner
=> $is_owner,
212 owners
=> $owner_ids,
215 cview_tmp_dir
=> $cview_tmp_dir,
216 cview_basepath
=> $c->get_conf('basepath'),
217 image_ids
=> $image_ids,
218 xrefs
=> \
@locus_xrefs,
219 trait_db_name
=> $trait_db_name,
221 src_feature
=> $src_feature,
223 locus_add_uri
=> $c->uri_for( '/ajax/locus/associate_locus' )->relative(),
224 cvterm_add_uri
=> $c->uri_for( '/ajax/locus/associate_ontology')->relative(),
225 assign_owner_uri
=> $c->uri_for( '/ajax/locus/assign_owner' )->relative(),
230 =head1 PRIVATE ACTIONS
234 Chain root for fetching a locus object to operate on.
236 Path part: /locus/<locus_id>
240 sub get_locus
: Chained
('/') PathPart
('locus') CaptureArgs
(1) {
241 my ($self, $c, $locus_id) = @_;
243 my $identifier_type = $c->stash->{identifier_type
}
244 || $locus_id =~ /[^-\d]/ ?
'locus' : 'locus_id';
246 if( $identifier_type eq 'locus_id' ) {
247 if ( $locus_id == 0 ) {
248 $c->stash->{locus
} = CXGN
::Phenome
::Locus
->new($c->dbc->dbh);
250 } elsif ( $locus_id < 0 ) {
251 $c->throw_client_error( public_message
=> 'Locus ID must be a positive integer.' );
254 #remove version numbers from locus name locus123.1.2
255 while ( $locus_id =~ m/.*\.\d+/ ) {
256 $locus_id =~ s/(.*)(\.\d+)/$1/ ;
259 my $matching_loci = $self->schema->resultset('Locus')->search(
261 $identifier_type => $locus_id,
265 if( $matching_loci->count > 1 ) {
266 $c->throw_client_error( public_message
=> 'Multiple matching loci' );
269 my ( $locus ) = $matching_loci->all
270 or $c->throw_404( "Locus not found" );
271 my $found_locus_id = $locus->locus_id;
273 $c->stash->{locus
} = CXGN
::Phenome
::Locus
->new($c->dbc->dbh, $found_locus_id);
282 sub get_locus_owner_ids
: Private
{
283 my ( $self, $c ) = @_;
284 my $locus = $c->stash->{locus
};
285 my @owner_ids = $locus ?
$locus->get_owners : ();
286 $c->stash->{owner_ids
} = \
@owner_ids;
289 sub get_locus_owner_objects
: Private
{
290 my ( $self, $c ) = @_;
291 my $locus = $c->stash->{locus
};
292 my $owner_objects = $locus ?
$locus->get_owners(1) : ();
293 $c->stash->{owner_objects
} = $owner_objects;
296 sub get_locus_extended_info
: Private
{
297 my ( $self, $c ) = @_;
298 $c->forward('get_locus_owner_ids');
303 #add the locus_dbxrefs to the stash.
304 sub get_locus_dbxrefs
: Private
{
305 my ( $self, $c ) = @_;
306 my $locus = $c->stash->{locus
};
307 my $locus_dbxrefs = $locus->get_dbxrefs;
308 $c->stash->{locus_dbxrefs
} = $locus_dbxrefs;
311 sub locus_dbxrefs_by_db
: Private
{
312 my ( $self, $c ) = @_;
313 my $locus = $c->stash->{locus
};
314 my %locus_dbxrefs = $locus->get_all_dbxrefs;
315 $c->stash->{locus_dbxrefs_by_db
} = \
%locus_dbxrefs;
319 sub _locus_pubs
: Private
{
320 my ($self, $c ) = @_;
321 my $dbxrefs = $c->stash->{locus_dbxrefs_by_db
};
323 my @sorted_pubs = ${$dbxrefs}{PMID
} ?
sort { $a->[0]->get_accession() <=> $b->[0]->get_accession() } @
{ ${$dbxrefs}{PMID
} } : () ;
324 my @sgn_ref = ${$dbxrefs}{SGN_ref
} ? @
{ ${$dbxrefs}{SGN_ref
} } : () ;
327 my @pub_dbxrefs = ( @sorted_pubs, @sgn_ref );
328 foreach my $d ( @pub_dbxrefs) {
329 if ( $d->[1] eq '0') { #if the dbxref is not obsolete
330 my $pub = CXGN
::Chado
::Publication
->new( $c->dbc->dbh, $d->[0]->get_publication()->get_pub_id() );
331 push @cxgn_pubs, $pub;
334 $c->stash->{pubs
} = \
@cxgn_pubs;
336 __PACKAGE__
->meta->make_immutable;