<commit_before>=head1 LICENSE

Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute 
Copyright [2016-2017] EMBL-European Bioinformatics Institute

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

=cut

package EnsEMBL::REST::Controller::VEP;
use Moose;
use namespace::autoclean;
use Data::Dumper;
use Bio::EnsEMBL::VEP::Runner;

use Try::Tiny;

require EnsEMBL::REST;

EnsEMBL::REST->turn_on_config_serialisers(__PACKAGE__);
BEGIN { 
  extends 'Catalyst::Controller::REST';
}

with 'EnsEMBL::REST::Role::PostLimiter';

# /vep/:species
sub get_species : Chained('/') PathPart('vep') CaptureArgs(1) {
  my ( $self, $c, $species ) = @_;
  my $reg = $c->model('Registry');
  $c->stash->{species} = $reg->get_alias($species);

  my ($csa, $css);
  try {
    $csa = $reg->get_adaptor($species, 'core', 'coordsystem');
  } catch {
    $c->go('ReturnError', 'from_ensembl', [qq{$_}]) if $_ =~ /STACK/;
    $c->go('ReturnError', 'custom', [qq{$_}]);
  };
  try {
    $css = $csa->fetch_all;
  } catch {
    $c->go('ReturnError', 'from_ensembl', [qq{$_}]) if $_ =~ /STACK/;
    $c->go('ReturnError', 'custom', [qq{$_}]);
  };

  $c->stash->{assembly} = $css->[0]->version;
  $c->stash->{has_variation} = $c->model('Registry')->get_adaptor( $species, 'Variation', 'Variation');
  $c->log->debug('Working with species '.$species);
}


# WARNING: Do not combine REST auto-dispatch with Args() or CaptureArgs()
# It prevents the dispatcher from recognising the GET and POST methods
# Arguments must be handled subsequently
sub get_region : Chained('get_species') PathPart('region') ActionClass('REST') {
  my ( $self, $c, $region ) = @_;
}

sub get_region_GET {
  my ( $self, $c, $region ) = @_;
  try {
    my ($sr_name) = $c->model('Lookup')->decode_region( $region, 1, 1 );
    my $slice = $c->model('Lookup')->find_slice( $sr_name );
  } catch {
    $c->go('ReturnError', 'from_ensembl', [qq{$_}]) if $_ =~ /STACK/;
    $c->go('ReturnError', 'custom', [qq{$_}]);
  };
  $self->status_ok( $c, entity => $region );
  $c->forward('get_allele');
}

sub get_region_POST {
  my ( $self, $c ) = @_;
  my $post_data = $c->req->data;

  # $c->log->debug(Dumper $post_data);
  # $c->log->debug(Dumper $config->{'Controller::VEP'});
  # handle user config
  my $config = $self->_include_user_params($c,$post_data);
  
  unless (exists $post_data->{variants}) {
    $c->go( 'ReturnError', 'custom', [ ' Cannot find "variants" key in your POST. Please check the format of your message against the documentation' ] );
  }
  my @variants = @{$post_data->{variants}};
  $self->assert_post_size($c,\@variants);

  $self->_give_POST_to_VEP($c,\@variants, $config);
}

sub _give_POST_to_VEP {
  my ($self,$c,$data,$config) = @_;
  try {    
    $config->{species} = $c->stash->{species}; # override VEP default for human
    my $consequences = $self->get_consequences($c, $config, join("\n", @$data));
    $c->stash->{consequences} = $consequences;
    $self->status_ok( $c, entity => $consequences );
  } catch {
    $c->log->fatal(qw{Problem Getting Consequences});
    $c->log->fatal($_);
    $c->log->fatal(Dumper $data);
    $c->go('ReturnError', 'from_ensembl', [qq{$_}]) if $_ =~ /STACK/;
    $c->go('ReturnError', 'custom', [qq{$_}]);
  };
}




# /vep/:species/region/:region/:allele_string
# Only one argument wanted here, but region is still on the stack and needs to be moved out of the way.
sub get_allele : PathPart('') Args(2) {
  my ( $self, $c, $region, $allele ) = @_;
  $c->log->debug($allele);
  my $s = $c->stash();
  if ($allele !~ /^[ATGC-]+$/i && $allele !~ /INS|DUP|DEL|TDUP/i) {
    my $error_msg = qq{Allele must be A,T,G,C or SO term [got: $allele]};
    $c->go( 'ReturnError', 'custom', [$error_msg] );
  }

  $s->{end} = $s->{start} if !$s->{end};
  $c->go('ReturnError', 'custom', ['Start or End cannot be negative']) if ($s->{start} < 0 || $s->{end} < 0);
  $c->go('ReturnError', 'custom', ['Strand should be 1 or -1, not ' . $s->{strand}]) if $s->{strand} !~ /1/;

  if($allele =~ /INS|DUP|DEL|TDUP/) {
    $s->{allele_string} = $allele;
    $s->{allele} = $allele;
  }
  else {
    my $reference_base;
    try {
      $reference_base = $s->{slice}->subseq( $s->{start}, $s->{end}, $s->{strand} );
      $s->{reference_base} = $reference_base;
    } catch {
      $c->log->fatal(qq{can't get reference base from slice});
      $c->go('ReturnError', 'from_ensembl', [qq{$_}]) if $_ =~ /STACK/;
      $c->go('ReturnError', 'custom', [qq{$_}]);
    };
    $c->go( 'ReturnError', 'custom', ["request for consequence of [$allele] matches reference [$reference_base]"] )
      if $reference_base eq $allele;
    my $allele_string = $reference_base . '/' . $allele;
    $s->{allele_string} = $allele_string;
    $s->{allele}        = $allele;
  }

  my $user_config = $c->request->parameters;<commit_msg>set default reference allele for insertion<commit_after>=head1 LICENSE

Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute 
Copyright [2016-2017] EMBL-European Bioinformatics Institute

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

=cut

package EnsEMBL::REST::Controller::VEP;
use Moose;
use namespace::autoclean;
use Data::Dumper;
use Bio::EnsEMBL::VEP::Runner;

use Try::Tiny;

require EnsEMBL::REST;

EnsEMBL::REST->turn_on_config_serialisers(__PACKAGE__);
BEGIN { 
  extends 'Catalyst::Controller::REST';
}

with 'EnsEMBL::REST::Role::PostLimiter';

# /vep/:species
sub get_species : Chained('/') PathPart('vep') CaptureArgs(1) {
  my ( $self, $c, $species ) = @_;
  my $reg = $c->model('Registry');
  $c->stash->{species} = $reg->get_alias($species);

  my ($csa, $css);
  try {
    $csa = $reg->get_adaptor($species, 'core', 'coordsystem');
  } catch {
    $c->go('ReturnError', 'from_ensembl', [qq{$_}]) if $_ =~ /STACK/;
    $c->go('ReturnError', 'custom', [qq{$_}]);
  };
  try {
    $css = $csa->fetch_all;
  } catch {
    $c->go('ReturnError', 'from_ensembl', [qq{$_}]) if $_ =~ /STACK/;
    $c->go('ReturnError', 'custom', [qq{$_}]);
  };

  $c->stash->{assembly} = $css->[0]->version;
  $c->stash->{has_variation} = $c->model('Registry')->get_adaptor( $species, 'Variation', 'Variation');
  $c->log->debug('Working with species '.$species);
}


# WARNING: Do not combine REST auto-dispatch with Args() or CaptureArgs()
# It prevents the dispatcher from recognising the GET and POST methods
# Arguments must be handled subsequently
sub get_region : Chained('get_species') PathPart('region') ActionClass('REST') {
  my ( $self, $c, $region ) = @_;
}

sub get_region_GET {
  my ( $self, $c, $region ) = @_;
  try {
    my ($sr_name) = $c->model('Lookup')->decode_region( $region, 1, 1 );
    my $slice = $c->model('Lookup')->find_slice( $sr_name );
  } catch {
    $c->go('ReturnError', 'from_ensembl', [qq{$_}]) if $_ =~ /STACK/;
    $c->go('ReturnError', 'custom', [qq{$_}]);
  };
  $self->status_ok( $c, entity => $region );
  $c->forward('get_allele');
}

sub get_region_POST {
  my ( $self, $c ) = @_;
  my $post_data = $c->req->data;

  # $c->log->debug(Dumper $post_data);
  # $c->log->debug(Dumper $config->{'Controller::VEP'});
  # handle user config
  my $config = $self->_include_user_params($c,$post_data);
  
  unless (exists $post_data->{variants}) {
    $c->go( 'ReturnError', 'custom', [ ' Cannot find "variants" key in your POST. Please check the format of your message against the documentation' ] );
  }
  my @variants = @{$post_data->{variants}};
  $self->assert_post_size($c,\@variants);

  $self->_give_POST_to_VEP($c,\@variants, $config);
}

sub _give_POST_to_VEP {
  my ($self,$c,$data,$config) = @_;
  try {    
    $config->{species} = $c->stash->{species}; # override VEP default for human
    my $consequences = $self->get_consequences($c, $config, join("\n", @$data));
    $c->stash->{consequences} = $consequences;
    $self->status_ok( $c, entity => $consequences );
  } catch {
    $c->log->fatal(qw{Problem Getting Consequences});
    $c->log->fatal($_);
    $c->log->fatal(Dumper $data);
    $c->go('ReturnError', 'from_ensembl', [qq{$_}]) if $_ =~ /STACK/;
    $c->go('ReturnError', 'custom', [qq{$_}]);
  };
}




# /vep/:species/region/:region/:allele_string
# Only one argument wanted here, but region is still on the stack and needs to be moved out of the way.
sub get_allele : PathPart('') Args(2) {
  my ( $self, $c, $region, $allele ) = @_;
  $c->log->debug($allele);
  my $s = $c->stash();
  if ($allele !~ /^[ATGC-]+$/i && $allele !~ /INS|DUP|DEL|TDUP/i) {
    my $error_msg = qq{Allele must be A,T,G,C or SO term [got: $allele]};
    $c->go( 'ReturnError', 'custom', [$error_msg] );
  }

  $s->{end} = $s->{start} if !$s->{end};
  $c->go('ReturnError', 'custom', ['Start or End cannot be negative']) if ($s->{start} < 0 || $s->{end} < 0);
  $c->go('ReturnError', 'custom', ['Strand should be 1 or -1, not ' . $s->{strand}]) if $s->{strand} !~ /1/;

  if($allele =~ /INS|DUP|DEL|TDUP/) {
    $s->{allele_string} = $allele;
    $s->{allele} = $allele;
  }
  else {
    my $reference_base;
    try {
      $reference_base = $s->{slice}->subseq( $s->{start}, $s->{end}, $s->{strand} );
      $s->{reference_base} = $reference_base;
    } catch {
      $c->log->fatal(qq{can't get reference base from slice});
      $c->go('ReturnError', 'from_ensembl', [qq{$_}]) if $_ =~ /STACK/;
      $c->go('ReturnError', 'custom', [qq{$_}]);
    };
    $c->go( 'ReturnError', 'custom', ["request for consequence of [$allele] matches reference [$reference_base]"] )
      if $reference_base eq $allele;

    $reference_base ||= '-';
    my $allele_string = $reference_base . '/' . $allele;
    $s->{allele_string} = $allele_string;
    $s->{allele}        = $allele;
  }

  my $user_config = $c->request->parameters;
{'fraction_non_alphanumeric': 0.20278218653720476, 'fraction_numerical': 0.005788441788815236, 'mean_word_length': 4.0409411764705885, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 181, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6520551', 'n_tokens_mistral': 4107, 'n_tokens_neox': 3916, 'n_words': 943}