Merge pull request #5191 from solgenomics/topic/quality_control
[sgn.git] / lib / CXGN / BrAPI / v2 / Variants.pm
blobf8a5b1ed5cfa6016c9d14b97d77b786720148eeb
1 package CXGN::BrAPI::v2::Variants;
3 use Moose;
4 use Data::Dumper;
5 use SGN::Model::Cvterm;
6 use CXGN::Marker::SearchBrAPI;
7 use CXGN::BrAPI::FileResponse;
8 use CXGN::BrAPI::Pagination;
9 use CXGN::BrAPI::JSONResponse;
10 use JSON;
12 use CXGN::DB::Connection;
14 extends 'CXGN::BrAPI::v2::Common';
16 sub search {
17 my $self = shift;
18 my $inputs = shift;
19 my $page_size = $self->page_size;
20 my $page = $self->page;
21 my $status = $self->status;
23 my $marker_ids = $inputs->{variantDbId} || ($inputs->{variantDbIds} || []);
24 my $variantset_ids = $inputs->{variantSetDbId} || ($inputs->{variantSetDbIds} || []);
25 my @callset_ids = $inputs->{callSetDbIds} ? @{$inputs->{callSetDbIds}} : ();
26 my $start = $inputs->{start}->[0] || undef;
27 my $end = $inputs->{end}->[0] || undef;
28 my $pageToken = $inputs->{pageToken}->[0] || undef;
29 my $schema = $self->bcs_schema;
30 my @data_out;
32 if (@callset_ids && scalar(@callset_ids)>0){
33 push @$status, { 'error' => 'The following search parameters are not implemented: callSetDbIds' };
36 my @trial_ids =();
37 my @protocol_ids = ();
38 if ( $variantset_ids){
39 foreach ( @{$variantset_ids} ){
40 my @ids = split /p/, $_;
41 push @trial_ids, $ids[0] ? $ids[0] : ();
42 push @protocol_ids, $ids[1] ? $ids[1] : ();
46 my $marker_search = CXGN::Marker::SearchBrAPI->new({
47 bcs_schema => $schema,
48 protocol_id_list => \@protocol_ids,
49 project_id_list => \@trial_ids,
50 marker_name_list => $marker_ids,
51 #protocolprop_marker_hash_select=>['name', 'chrom', 'pos', 'alt', 'ref'] Use default which is all marker info
52 offset=>$page_size*$page,
53 limit=>$page_size
54 });
56 my $start_index = $page*$page_size;
57 my $end_index = $page*$page_size + $page_size - 1;
58 my $counter = 0;
60 my ($data, $total_count) = $marker_search->search();
62 foreach (@$data){
63 if ($counter >= $start_index && $counter <= $end_index) {
64 my $info = $_->{info};
65 my $svtype = $1 if ($_->{info} =~ /SVTYPE=(\w+);/) ;
66 my @cipos = _get_info($info,'CIPOS');
67 my @ciend = _get_info($info,'CIEND');
68 my @svlen = _get_info($info,'SVLEN');
70 my %data_obj = (
71 additionalInfo => {},
72 alternate_bases => $_->{alt},
73 ciend => [@ciend],
74 cipos => [@cipos],
75 created => undef,
76 end => $_->{pos} + length($_->{ref}),
77 filtersApplied => $_->{filter} eq "." ? JSON::false : JSON::true,
78 filtersFailed => ( $_->{filter} eq "PASS" || $_->{filter} eq "." ) ? undef : $_->{filter},
79 filtersPassed => $_->{filter} eq "PASS" ? JSON::true : JSON::false,
80 referenceBases => $_->{ref},
81 referenceName => $_->{chrom} ? $_->{chrom} : undef,
82 start => $_->{pos},
83 svlen => @svlen,
84 updated => undef,
85 variantDbId => qq|$_->{marker_name}|,
86 variantNames => $_->{marker_name},
87 variantSetDbId => _quote($_->{project_id}, $_->{nd_protocol_id} ),
88 variantType => $svtype,
90 push @data_out, \%data_obj;
92 $counter++;
95 my %result = (data=>\@data_out);
96 my @data_files;
97 my $pagination = CXGN::BrAPI::Pagination->pagination_response($counter,$page_size,$page);
98 return CXGN::BrAPI::JSONResponse->return_success(\%result, $pagination, \@data_files, $status, 'Variants result constructed');
101 sub detail {
102 my $self = shift;
103 my $inputs = shift;
104 my $page_size = $self->page_size;
105 my $page = $self->page;
106 my $status = $self->status;
107 my @marker_ids;
109 my $marker_ids = $inputs->{variantDbId};
111 my $schema = $self->bcs_schema;
112 my @data_out;
115 my $marker_search = CXGN::Marker::SearchBrAPI->new({
116 bcs_schema => $schema,
117 protocol_id_list => [],
118 marker_name_list => [$marker_ids],
121 my ($data, $total_count) = $marker_search->search();
123 foreach (@$data){
124 my $info = $_->{info};
125 my $svtype = $1 if ($_->{info} =~ /SVTYPE=(\w+);/) ;
126 my @cipos = _get_info($info,'CIPOS');
127 my @ciend = _get_info($info,'CIEND');
128 my @svlen = _get_info($info,'SVLEN');
130 my %data_obj = (
131 additionalInfo => {},
132 alternate_bases => $_->{alt},
133 ciend => [@ciend],
134 cipos => [@cipos],
135 created => undef,
136 end => $_->{pos} + length($_->{ref}),
137 filtersApplied => $_->{filter} eq "." ? JSON::false : JSON::true,
138 filtersFailed => ( $_->{filter} eq "PASS" || $_->{filter} eq "." ) ? undef : $_->{filter},
139 filtersPassed => $_->{filter} eq "PASS" ? JSON::true : JSON::false,
140 referenceBases => $_->{ref},
141 referenceName => $_->{chrom} ? 'chr_' . $_->{chrom} : undef,
142 start => $_->{pos},
143 svlen => @svlen, #length($_->{alt}),
144 updated => undef,
145 variantDbId => qq|$_->{marker_name}|,
146 variantNames => $_->{marker_name},
147 variantSetDbId => _quote($_->{project_id}, $_->{nd_protocol_id} ),
148 variantType => $svtype,
150 push @data_out, \%data_obj;
153 my %result = (data=>\@data_out);
154 my @data_files;
155 my $pagination = CXGN::BrAPI::Pagination->pagination_response(1,$page_size,$page);
156 return CXGN::BrAPI::JSONResponse->return_success(\%result, $pagination, \@data_files, $status, 'Variants result constructed');
160 sub calls {
161 my $self = shift;
162 my $inputs = shift;
163 my $c = $self->context;
164 my $page_size = $self->page_size;
165 my $page = $self->page;
166 my $status = $self->status;
167 my $sep_phased = $inputs->{sep_phased};
168 my $sep_unphased = $inputs->{sep_unphased};
169 my $unknown_string = $inputs->{unknown_string};
170 my $expand_homozygotes = $inputs->{expand_homozygotes};
171 my $marker_id = $inputs->{variantDbId};
172 my @trial_ids;
174 if ($sep_phased || $sep_unphased || $expand_homozygotes || $unknown_string){
175 push @$status, { 'error' => 'The following parameters are not implemented: expandHomozygotes, unknownString, sepPhased, sepUnphased' };
178 my $trial_search = CXGN::Trial::Search->new({
179 bcs_schema=>$self->bcs_schema,
180 trial_design_list=>['genotype_data_project']
182 my ($data, $total_count) = $trial_search->search();
184 foreach (@$data){
185 push @trial_ids, $_->{trial_id};
188 my @data_files;
189 my %result;
191 my $genotypes_search = CXGN::Genotype::Search->new({
192 bcs_schema=>$self->bcs_schema,
193 cache_root=>$c->config->{cache_file_path},
194 people_schema => $self->people_schema(),
195 trial_list=>\@trial_ids,
196 genotypeprop_hash_select=>['DS', 'GT', 'NT'],
197 protocolprop_top_key_select=>[],
198 protocolprop_marker_hash_select=>[],
200 my $file_handle = $genotypes_search->get_cached_file_search_json($c->config->{cluster_shared_tempdir}, 0);
202 my $start_index = $page*$page_size;
203 my $end_index = $page*$page_size + $page_size - 1;
204 my $counter = 0;
206 open my $fh, "<&", $file_handle or die "Can't open output file: $!";
207 my $header_line = <$fh>;
209 my @data;
211 while (my $gt_line = <$fh>) {
212 my $gt = decode_json $gt_line;
213 my $genotype = $gt->{selected_genotype_hash};
214 my @ordered_refmarkers = sort keys(%$genotype);
215 my $genotypeprop_id = $gt->{markerProfileDbId};
217 foreach my $m (@ordered_refmarkers) {
218 if ($m eq $marker_id){
219 if ($counter >= $start_index && $counter <= $end_index) {
220 my $geno = '';
221 if (exists($genotype->{$m}->{'NT'}) && defined($genotype->{$m}->{'NT'})){
222 $geno = $genotype->{$m}->{'NT'};
224 elsif (exists($genotype->{$m}->{'GT'}) && defined($genotype->{$m}->{'GT'})){
225 $geno = $genotype->{$m}->{'GT'};
227 elsif (exists($genotype->{$m}->{'DS'}) && defined($genotype->{$m}->{'DS'})){
228 $geno = $genotype->{$m}->{'DS'};
230 push @data, {
231 additionalInfo=>undef,
232 variantName=>qq|$m|,
233 variantDbId=>qq|$m|,
234 callSetDbId=>qq|$gt->{stock_id}|,
235 callSetName=>qq|$gt->{stock_name}|,
236 genotype=>{values=>$geno},
237 genotype_likelihood=>undef,
238 phaseSet=>undef,
241 $counter++;
246 %result = ( data=>\@data,
247 expandHomozygotes=>undef,
248 sepPhased=>undef,
249 sepUnphased=>undef,
250 unknownString=>undef);
254 my $pagination = CXGN::BrAPI::Pagination->pagination_response($counter,$page_size,$page);
255 return CXGN::BrAPI::JSONResponse->return_success(\%result, $pagination, \@data_files, $status, 'VariantSets result constructed');
258 sub _get_info {
259 my $info = shift;
260 my $item = shift;
261 my @array = [];
263 #match with CIPOS=-22,18;CIEND=-12,32"
264 if ( $info =~ /$item=(-?(\d+),?)+/) {
265 my $match = $&;
266 $match =~ s/$item=//g;
267 my @splited = split(/,/, $match);
268 @array = map { $_ + 0 } @splited;
271 return @array ;
274 sub _quote {
275 my $array = shift;
276 my $protocol = shift;
278 foreach (@$array) {
279 $_ = "$_" . "p". $protocol;
282 return $array