<commit_before>#
#
#
=pod 

=head1 NAME

  Bio::EnsEMBL::Pipeline::Runnable::ProteinAnnotation::PIRSF

=head1 SYNOPSIS

  my $seg = Bio::EnsEMBL::Pipeline::Runnable::ProteinAnnotation::PIRSF->
    new ( 
    -query      => $query,
    -analysis   => $analysis,
    -database   => $db,
    -datfile    => $datfile,
    );
    

=head1 DESCRIPTION

=head1 CONTACT

=cut

package Bio::EnsEMBL::Analysis::Runnable::ProteinAnnotation::PIRSF;

use strict;
use vars qw(@ISA);

use Bio::EnsEMBL::Utils::Exception qw(throw warning);
use Bio::EnsEMBL::Utils::Argument qw(rearrange);

use Bio::EnsEMBL::Analysis::Runnable::ProteinAnnotation;
use Bio::EnsEMBL::Analysis::Runnable::ProteinAnnotation::Hmmpfam;

@ISA = qw(Bio::EnsEMBL::Analysis::Runnable::ProteinAnnotation);


sub multiprotein{
  my ($self) = @_;
  return 1;
}


###############################
sub run_analysis {
  my ($self) = @_;

  my $dat = $self->process_thresholds_file($self->thresholds);

  my ($main_hmm, $sf_hmm) = split(/;/, $self->database);

  my $main_run = Bio::EnsEMBL::Analysis::Runnable::ProteinAnnotation::Hmmpfam->
      new(-query => $self->query,
          -analysis => $self->analysis,
          -database => $main_hmm,
          -options  => $self->options);
  $main_run->run;

  my $best_hit = $self->filter_main($main_run->output, $dat);

  if (defined $best_hit and exists($dat->{$best_hit->hseqname}->{children})) {
    my $sf_run = Bio::EnsEMBL::Analysis::Runnable::ProteinAnnotation::Hmmpfam->
        new(-query => $self->query,
            -analysis => $self->analysis,
            -database => $sf_hmm,
            -options  => $self->options);
    $sf_run->run;

    my @relevant_hits;
    foreach my $hit (@{$sf_run->output}) {
      if ($dat->{$best_hit->hseqname}->{children}->{$hit->hseqname}) {
        push @relevant_hits, $hit;
      }
    }

    if (@relevant_hits) {
      my $best_sf_hit = $self->filter_sub_family(\@relevant_hits, $dat);
      if (defined $best_sf_hit) {
        $best_hit = $best_sf_hit;
      }
    }
  }

  my $out = [];
  if (defined $best_hit) {
    push @$out, $best_hit;
  }

  $self->output($out);
}


sub parse_results {
  my ($self) = @_;
  
  # nothing to do
  return;
}



###############################
sub filter_main {
  my ($self, $hits, $dat) = @_;

  my @pass_hits;

  my %seqlengths;

  my $seqio = Bio::SeqIO->new(-format => 'fasta',
                              -file   => $self->queryfile);
  while (my $seq = $seqio->next_seq) {
    $seqlengths{$seq->id} = $seq->length;
  }
  $seqio->close;

  foreach my $hit (@$hits) {
    my $this_dat = $dat->{$hit->hseqname};
    
    if (not defined $this_dat->{mean_score}) {
      # this must be a sub-family hit; filter it out, hoping 
      # that the superfamily will be hit, and hence this sub-family 
      # hit in the refined search
      next;
    }

    my $len_prop = $hit->length / $seqlengths{$hit->seqname};
    my $len_diff = abs($seqlengths{$hit->seqname} - $this_dat->{mean_length});
    my $score_diff = $hit->score - $this_dat->{mean_score};

    if ($len_prop >= 0.8 and
        ($score_diff >= -1*$this_dat->{std_score} or 
         ($hit->score >= $this_dat->{min_score} and 
          $score_diff >= -2.5 * $this_dat->{std_score})) and
        ($len_diff < 3.5 * $this_dat->{std_length})) {
      push @pass_hits, $hit;
    }
  }

  if (@pass_hits) {
    @pass_hits = sort { $a->p_value <=> $b->p_value} @pass_hits;
    return $pass_hits[0];
  } else {
    return undef;
  }
}


sub filter_sub_family {
  my ($self, $hits, $dat);
  
  my @pass_hits;
    foreach my $hit (@$hits) {<commit_msg>changed so it can run on translation chunks and return all the results<commit_after>#
#
#
=pod 

=head1 NAME

  Bio::EnsEMBL::Pipeline::Runnable::ProteinAnnotation::PIRSF

=head1 SYNOPSIS

  my $seg = Bio::EnsEMBL::Pipeline::Runnable::ProteinAnnotation::PIRSF->
    new ( 
    -query      => $query,
    -analysis   => $analysis,
    -database   => $db,
    -datfile    => $datfile,
    );
    

=head1 DESCRIPTION

=head1 CONTACT

=cut

package Bio::EnsEMBL::Analysis::Runnable::ProteinAnnotation::PIRSF;

use strict;
use vars qw(@ISA);

use Bio::EnsEMBL::Utils::Exception qw(throw warning);
use Bio::EnsEMBL::Utils::Argument qw(rearrange);

use Bio::EnsEMBL::Analysis::Runnable::ProteinAnnotation;
use Bio::EnsEMBL::Analysis::Runnable::ProteinAnnotation::Hmmpfam;

@ISA = qw(Bio::EnsEMBL::Analysis::Runnable::ProteinAnnotation);


sub multiprotein{
  my ($self) = @_;
  return 1;
}


###############################
sub run_analysis {
  my ($self) = @_;

  my $dat = $self->process_thresholds_file($self->thresholds);

  my ($main_hmm, $sf_hmm) = split(/;/, $self->database);

  my $out = [] ;
  my $seqio = Bio::SeqIO->new(-format => 'fasta',
                              -file   => $self->queryfile);
  while (my $seq = $seqio->next_seq) {
    my $main_run = Bio::EnsEMBL::Analysis::Runnable::ProteinAnnotation::Hmmpfam->
      new(-query => $seq,
          -analysis => $self->analysis,
          -database => $main_hmm,
          -options  => $self->options);
    $main_run->run;
    my $best_hit = $self->filter_main($main_run->output, $dat, $seq);

    if (defined $best_hit and exists($dat->{$best_hit->hseqname}->{children})) {
      my $sf_run = Bio::EnsEMBL::Analysis::Runnable::ProteinAnnotation::Hmmpfam->
        new(-query => $seq,
            -analysis => $self->analysis,
            -database => $sf_hmm,
            -options  => $self->options);
      $sf_run->run;

      my @relevant_hits;
      foreach my $hit (@{$sf_run->output}) {
        if ($dat->{$best_hit->hseqname}->{children}->{$hit->hseqname}) {
          push @relevant_hits, $hit;
        }
      }

      if (@relevant_hits) {
        my $best_sf_hit = $self->filter_sub_family(\@relevant_hits, $dat);
        if (defined $best_sf_hit) {
          $best_hit = $best_sf_hit;
        }
      }
    }

    if (defined $best_hit) {
      push @$out, $best_hit;
    }
  }
  $seqio->close;

  $self->output($out);
}


sub parse_results {
  my ($self) = @_;
  
  # nothing to do
  return;
}



###############################
sub filter_main {
  my ($self, $hits, $dat, $seq) = @_;

  my @pass_hits;

  foreach my $hit (@$hits) {
    my $this_dat = $dat->{$hit->hseqname};
    
    if (not defined $this_dat->{mean_score}) {
      # this must be a sub-family hit; filter it out, hoping 
      # that the superfamily will be hit, and hence this sub-family 
      # hit in the refined search
      next;
    }

    my $len_prop = $hit->length / $seq->length ;
    my $len_diff = abs($seq->length - $this_dat->{mean_length});
    my $score_diff = $hit->score - $this_dat->{mean_score};

    if ($len_prop >= 0.8 and
        ($score_diff >= -1*$this_dat->{std_score} or 
         ($hit->score >= $this_dat->{min_score} and 
          $score_diff >= -2.5 * $this_dat->{std_score})) and
        ($len_diff < 3.5 * $this_dat->{std_length})) {
      push @pass_hits, $hit ;
    }
  }

  if (@pass_hits) {
    @pass_hits = sort { $a->p_value <=> $b->p_value} @pass_hits;
    return $pass_hits[0];
  } else {
    return undef;
  }
}


sub filter_sub_family {
  my ($self, $hits, $dat);
  
  my @pass_hits;
    foreach my $hit (@$hits) {
{'fraction_non_alphanumeric': 0.19028452463566967, 'fraction_numerical': 0.0036086051353226927, 'mean_word_length': 2.9377049180327868, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 135, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '5043697', 'n_tokens_mistral': 2771, 'n_tokens_neox': 2607, 'n_words': 510}