can download plant phenotype data in the same way as plot phenotype data
[sgn.git] / lib / SGN / Controller / solGS / solgsStock.pm
blob4c0298452a5f8eb88a4a2c91db119ca0b72dd069
1 package SGN::Controller::solGS::solgsStock;
3 =head1 NAME
5 solGS::Controller::Stock - Catalyst controller for phenotyping and genotyping data related to stocks (e.g. accession, plot, population, etc.)
7 =cut
9 use Moose;
10 use namespace::autoclean;
11 use YAML::Any qw/LoadFile/;
13 use URI::FromHash 'uri';
14 use List::Compare;
15 use File::Temp qw / tempfile /;
16 use File::Slurp;
17 use JSON::Any;
18 use List::MoreUtils qw / uniq /;
19 use Bio::Chado::NaturalDiversity::Reports;
21 BEGIN { extends 'Catalyst::Controller' }
22 with 'Catalyst::Component::ApplicationAttribute';
24 has 'schema' => (
25 is => 'rw',
26 isa => 'DBIx::Class::Schema',
27 lazy_build => 1,
30 sub _build_schema {
31 shift->_app->dbic_schema( 'Bio::Chado::Schema', 'sgn_chado' )
34 sub validate_stock_list {
35 my ($self, $c) = shift;
36 #check here the list of submitted stocks
38 my $stock_names; #array ref of names - convert all to lower case ?
39 #search the stock table and return error message if some stocks were not found
40 my $stock_rs = $self->schema->resultset('Stock::Stock' , {
41 -or => [
42 'lower(me.name)' => { -in => $stock_names } ,
43 'lower(me.uniquename)' => { -in => $stock_names },
44 -and => [
45 'lower(type.name)' => { like =>'%synonym%' },
46 'lower(stockprops.value)' => { -in => $stock_names },
49 } ,
50 { join => { 'stockprops' => 'type' } ,
51 columns => [ qw/stock_id uniquename type_id organism_id / ],
52 distinct => 1
55 return $self->_filter_stock_rs($c,$stock_rs);
58 # select stock_rs for genomic selection tool
59 sub _filter_stock_rs {
60 my ( $self, $c, $rs ) = @_;
62 # filter by genoytpe and phenotype experiments
63 #check if there are any direct or indirect phenotypes scored on this stock
64 print STDERR "\n\n check if there are any direct or indirect phenotypes scored on this stock..\n\n";
65 my $recursive_phenotypes = $self->schema->resultset("Stock::Stock")->recursive_phenotypes_rs($rs);
66 my @r_stocks;
67 foreach my $p_rs (@$recursive_phenotypes) {
68 while ( my $r = $p_rs->next ) {
69 my $observable = $r->get_column('observable');
70 next if !$observable;
71 no warnings 'uninitialized';
72 push @r_stocks, ( $r->get_column('stock_id') );
75 #filter the rs by the stock_ids above with scored phenotypes
76 print STDERR "\n\nfilter the rs by the stock_ids above with scored phenotypes\n\n";
77 $rs = $rs->search(
79 'me.stock_id' => { -in => \@r_stocks },
84 $rs = $rs->search(
86 'type.name' => 'genotyping_experiment'
87 } ,
88 { join => {nd_experiment_stocks => { nd_experiment => 'type' } } ,
89 distinct => 1
90 } );
93 # # optional - filter by project name , project year, location
94 # if( my $project_ids = $c->req->param('projects') ) {
95 # # filter by multiple project names select box should allow selecting of multiple
96 # # project names. Value is a listref of project_ids
97 # $rs = $rs->search(
98 # { 'project.project_id' => { -in => $project_ids },
99 # },
100 # { join => { nd_experiment_stocks => { nd_experiment => { 'nd_experiment_project' => 'project' }}},
101 # distinct => 1
102 # } );
104 # if (my $years = $c->req->param('years') ) {
105 # # filter by multiple years. param is a listref of values
106 # $rs = $rs->search(
107 # { 'projectprop.value' => { -in => $years },
108 # 'lower(type.name)' => { like => '%year%' }
109 # },
110 # { join => { nd_experiment_stocks => { nd_experiment => { 'nd_experiment_project' => { 'project' => { 'projectprops' => 'type' }}}}},
111 # distinct => 1
112 # });
114 # if( my $location_ids = $c->req->param('locations') ) {
115 # # filter by multiple locations. param is listref of nd_geolocation_ids
116 # $rs = $rs->search(
117 # { 'nd_experiment.nd_geolocation_id' => { -in => $location_ids },
118 # },
119 # { join => { nd_experiment_stocks => ' nd_experiment' },
120 # distinct => 1
121 # });
123 return $rs;
126 sub project_years {
127 my ($self, $c) = shift;
128 my $years_rs = $self->schema->resultset("Project::Projectprop")->search(
130 'lower(type.name)' => { like => '%year%' }
132 { join => 'type',
133 distinct => 1
134 } ); #->get_column('value');
136 return $years_rs;
141 sub locations {
142 my ($self, $c) = shift;
143 my $locations_rs = $self->schema->resultset("NaturalDiversity::NdGeolocation")->search(
144 {} );#->get_column('description');
146 return $locations_rs;
148 =head1 PRIVATE ACTIONS
150 =head2 solgs_download_phenotypes
152 =cut
155 sub solgs_download_phenotypes : Path('/solgs/phenotypes') Args(1) {
156 my ($self, $c, $stock_id ) = @_; # stock should be population type only?
158 if ($stock_id) {
159 $c->stash->{pop_id} = $stock_id;
160 $c->controller('Root')->phenotype_file($c);
161 my $d = read_file($c->stash->{phenotype_file});
162 my @info = split(/\n/ , $d);
163 my @data;
164 foreach (@info) {
165 push @data, [ split(/\t/) ] ;
168 $c->stash->{'csv'}={ data => \@data};
169 $c->forward("View::Download::CSV");
174 =head2 download_genotypes
176 =cut
179 sub download_genotypes : Path('genotypes') Args(1) {
180 my ($self, $c, $stock_id ) = @_;
181 my $stock = $c->stash->{stock_row};
182 $stock_id = $stock->stock_id;
183 my $stock_name = $stock->uniquename;
184 if ($stock_id) {
185 my $tmp_dir = $c->get_conf('basepath') . "/" . $c->get_conf('stock_tempfiles');
186 my $file_cache = Cache::File->new( cache_root => $tmp_dir );
187 $file_cache->purge();
188 my $key = "stock_" . $stock_id . "_genotype_data";
189 my $gen_file = $file_cache->get($key);
190 my $filename = $tmp_dir . "/stock_" . $stock_id . "_genotypes.csv";
191 unless ( -e $gen_file) {
192 my $gen_hashref; #hashref of hashes for the phenotype data
193 my %cvterms ; #hash for unique cvterms
194 ##############
195 my $genotypes = $self->_stock_project_genotypes( $stock );
196 write_file($filename, ("project\tmarker\t$stock_name\n") );
197 foreach my $project (keys %$genotypes ) {
198 #my $genotype_ref = $genotypes->{$project} ;
199 #my $replicate = 1;
200 foreach my $geno (@ { $genotypes->{$project} } ) {
201 my $genotypeprop_rs = $geno->search_related('genotypeprops', {
202 #this is the current genotype we have , add more here as necessary
203 'type.name' => 'infinium array' } , {
204 join => 'type' } );
205 while (my $prop = $genotypeprop_rs->next) {
206 my $json_text = $prop->value ;
207 my $genotype_values = JSON::Any->decode($json_text);
208 foreach my $marker_name (keys %$genotype_values) {
209 my $read = $genotype_values->{$marker_name};
210 write_file( $filename, { append => 1 } , ($project, "\t" , $marker_name, "\t", $read, "\n") );
215 $file_cache->set( $key, $filename, '30 days' );
216 $gen_file = $file_cache->get($key);
218 my @data;
219 foreach ( read_file($filename) ) {
220 push @data, [ split(/\t/) ];
222 $c->stash->{'csv'}={ data => \@data};
223 $c->forward("View::Download::CSV");
231 __PACKAGE__->meta->make_immutable;